--- /dev/null
+unrecognized ^(.*\.rej)$
+precious ^(.*\.elc|(auto-autoloads|custom-(load|defines)|emchat-version)\.el|emchat\.info|TAGS)$
+precious ^(emchat-version.texi)$
+precious ^(prepsrc.el)$
--- /dev/null
+This is the old ChangeLog from when Eicq was in CVS at SF.net
+
+2004-06-09 Steve Youngs <steve@youngs.au.com>
+
+ * eicq-log.el (eicq-log-buddy-message): Remove call to
+ `goto-addr'. We'll write our own using XEmacs extents.
+ Don't require goto-addr.el, so we don't need the fsf-compat
+ package.
+
+2004-06-09 Steve Youngs <steve@youngs.au.com>
+
+ * eicq-v8.el: New file.
+
+2004-05-30 Steve Youngs <steve@youngs.au.com>
+
+ * *: Update copyright notices and my email address.
+
+2003-10-17 Steve Youngs <sryoungs@bigpond.net.au>
+
+ * eicq-v8proto.el (eicq::CLI_IDENT): Comment out entries that were
+ causing "Variable binding depth exceeds max-specpdl-size" errors.
+ BE AWARE! The code is STILL broken, this is just a temporary
+ workaround so that Eicq compiles.
+
+ * Makefile (distclean): Delete the TAGS file too.
+
+2003-10-15 Steve Youngs <sryoungs@bigpond.net.au>
+
+ * Makefile (EMACS): Removed, this is XEmacs not Emacs.
+ (EMACS_FLAGS): Ditto.
+ (XEMACS): New.
+ (XEMACS_FLAGS): New, add '-no-autoloads' to ensure we are building
+ in a clean environment.
+ (AUTO_PRELOADS): Removed.
+ (AUTOLOAD_PACKAGE_NAME): New.
+ (AUTOLOAD_FILE): New.
+ (all): Use 'compile' target instead of '$(OBJECTS)'. This is so
+ we can compile all the .el files from a single instance of
+ XEmacs. The old way loaded XEmacs for each and every file that
+ was built.
+ (.el.elc): Removed.
+ (compile): New.
+ (auto-autoloads.el): Set it up to use '-no-autoloads'
+ (custom-loads.el): Ditto.
+ (distclean): Remove core* files.
+
+ * eicq-buddy.el: Require advice at compile time.
+
+ * eicq-comm.el: Require passwd at compile time.
+ (eicq-encrypt-password): Return in hex.
+
+ * eicq-log.el: Require smiley and goto-addr at compile time.
+
+ * eicq-report.el: Require font-lock, yow, and pp at compile time.
+
+ * eicq-v8proto.el: Require eicq-world, eicq.
+ (eicq-put-alist): Removed.
+ (eicq-alist-hex-to-bin): Simplified.
+ (eicq-fun-hex-to-bin): New.
+ (deficq): Simplified.
+ (eicq-valid-prefix-list): New.
+
+ * eicq-world.el: Require font-lock and sort at compile time.
+
+ * eicq.el: Require ehelp, cus-edit, browse-url, and passwd at
+ compile time.
+
+2003-10-02 Steve Youngs <sryoungs@bigpond.net.au>
+
+ * README: Update my email address.
+
+ * eicq-v8proto.el: Ditto.
+
+ * eicq.el: Ditto.
+
+ * eicq-world.el: Ditto.
+
+ * eicq-toolbar.el: Ditto.
+
+ * eicq-status.el: Ditto.
+
+ * eicq-setup.el: Ditto.
+
+ * eicq-report.el: Ditto.
+ (eicq-prepare-email-author): Ditto.
+
+ * eicq-meta.el: Ditto.
+
+ * eicq-menu.el: Ditto.
+
+ * eicq-log.el: Ditto.
+
+ * eicq-comm.el: Ditto.
+
+ * eicq-buddy.el: Ditto.
+
+2003-10-01 Steve Youngs <youngs@xemacs.org>
+
+ * eicq-v8proto.el (eicq::CLI_IDENT): Fix 'Invalid read syntax:
+ ". in wrong context"' error.
+ (eicq::CLI_SETSTATUS): Ditto.
+
+2003-09-19 Steve Youngs <youngs@xemacs.org>
+
+ * *: Update to BSD license.
+
+ * eicq.el (eicq-copyright): A function to satisfy condition 2 of
+ the BSD license.
+
+ * eicq.texi: Removed practically everything in the file because it
+ desparately needs a complete rewrite.
+
+ * infohack.el: Removed.
+
+ * Makefile (MAKEINFO): New.
+ (.texi.info): Use it.
+ (EICQ_INFO_COMPILE): Removed.
+
+2003-09-06 Steve Youngs <youngs@xemacs.org>
+
+ * Makefile (VER): Bump.
+
+ * eicq-comm.el (eicq-network-buffer):
+ (eicq-network-hostname): Removed.
+ (eicq-server-hostname):
+ (eicq-network-port): Removed.
+ (eicq-local-network-p): Removed.
+ (eicq-network):
+ (eicq-int-byte):
+ (eicq-network-kill):
+ (eicq-connected-p):
+ (eicq-binary-process): New.
+ (eicq-connect):
+
+ * eicq-convert.el:
+
+ * eicq-meta.el (eicq-pack):
+
+ * eicq-report.el (eicq-version):
+ * eicq-status.el:
+
+ * eicq-toolbar.el (eicq-change-password):
+
+ * eicq-v8proto.el (eicq-use-firewall): New.
+ (eicq-hex-to-bin): New.
+ (eicq-put-alist): New.
+ (eicq-alist-hex-to-bin): New.
+ (deficq): New.
+ (eicq::FLAP_header): New.
+ (eicq::FLAP_channels): New.
+ (eicq::CLI_bytefiller): New.
+ (eicq::CLI_IDENT): New.
+ (eicq::CLI_READY): New.
+ (eicq::CLI_RATESREQUEST): New.
+ (eicq::CLI_ACKRATES): New.
+ (eicq::CLI_REQINFO): New.
+ (eicq::CLI_SNAC1_11): New.
+ (eicq::CLI_FAMILIES): New.
+ (eicq::CLI_SETSTATUS): New.
+ (eicq::CLI_REQLOCATION): New.
+ (eicq::CLI_SETUSERINFO): New.
+ (eicq::CLI_REQBUDDY): New.
+ (eicq::CLI_ADDCONTACT): New.
+ (eicq::CLI_REMCONTACT): New.
+ (eicq::CLI_SETICBM): New.
+ (eicq::CLI_REQICBM): New.
+ (eicq::CLI_REQBOS): New.
+
+ * eicq-world.el:
+
+ * eicq.el (eicq-version):
+ (eicq-status-auto-reply):
+ (eicq-frame):
+ (eicq-network-show-buffer): Removed.
+ (eicq-send-internal):
+ (eicq-pack-login-a):
+ (eicq-login):
+
+ Big huge changes trying to get ICQv8 protocol working. This is a
+ long way from complete and Eicq is totally broken at this point.
+
+2003-03-02 Steve Youngs <youngs@xemacs.org>
+
+ * eicq-v8proto.el (deficq): New macro to define ICQ packets.
+
+2002-10-03 Steve Youngs <youngs@xemacs.org>
+
+ * etc/*: Removed, we do it all in lisp now.
+
+ * eicq-buddy.el (eicq-buddy-status-color-hint-flag): Removed.
+ (eicq-face-online): Removed.
+ (eicq-face-away): Removed.
+ (eicq-face-occ): Removed.
+ (eicq-face-dnd): Removed.
+ (eicq-face-ffc): Removed.
+ (eicq-face-na): Removed.
+ (eicq-face-offline): Removed.
+ (eicq-buddy-update-status): Removed.
+
+ * NEWS: Updated.
+
+ * TODO: Updated.
+
+ * INSTALL: Updated.
+
+ * eicq-convert.el: Update requires
+
+ * eicq-report.el (eicq-report-debug): Add missing .el files.
+
+ * eicq-toolbar.el (eicq-icon-directory): Removed.
+ (eicq-use-toolbar): Test for featurep 'xpm.
+ (eicq-password-icon): Create toolbar icon in lisp.
+ (eicq-send-message-here-icon): Ditto.
+ (eicq-send-message-around-icon): Ditto.
+ (eicq-send-url-here-icon): Ditto.
+ (eicq-send-url-around-icon): Ditto.
+ (eicq-query-info-here-icon): Ditto.
+ (eicq-query-info-around-icon): Ditto.
+ (eicq-update-info-icon): Ditto.
+ (eicq-search-icon): Ditto.
+ (eicq-authorize-here-icon): Ditto.
+ (eicq-login-icon): Ditto.
+ (eicq-logout-icon): Ditto.
+ (eicq-disconnect-icon): Ditto.
+ (eicq-new-log-icon): Ditto.
+ (eicq-help-icon): Ditto.
+
+ * .cvsignore: Updated.
+
+ * Makefile (DATA_DIR): Removed.
+ (BIN_DIR): Removed.
+ (BIN_STAGING): Removed.
+ (DATA_STAGING): Removed.
+ (INSTALL): Remove the BIN and DATA stuff.
+ (SOURCES): Use a wildcard instead of listing each file.
+
+ * eicq-menu.el (eicq-main-map): Autoload it.
+ (eicq-global-map-set): Ditto.
+ (eicq-global-key-prefix): Ditto.
+ (eicq-log-mode-map): Ditto.
+ (eicq-alias-map): Ditto.
+ (eicq-url-map): Ditto.
+ (eicq-buddy-mode-map): Ditto.
+
+ * eicq-world.el (eicq-world): New.
+ (eicq-all-aliases): New.
+ (eicq-world-rc-regexp): New.
+ (Format): New.
+ (unknown)): New.
+ (unknown-2)): New.
+ (eicq-do-meta-user-work): New.
+ (eicq-do-meta-user-more): New.
+ (Language-1): New.
+ (Language-2): New.
+ (Language-3): New.
+ (eicq-do-meta-user-about): New.
+ (eicq-do-meta-user-interest): New.
+ (eicq-do-meta-user-background): New.
+ (eicq-do-meta-user-picture): New.
+ (eicq-do-meta-user-found): New.
+ (eicq-do-meta-user-update-general-confirm): New.
+ (eicq-do-meta-user-update-work-confirm): New.
+ (eicq-do-meta-user-update-more-confirm): New.
+ (eicq-do-meta-user-update-about-confirm): New.
+ (eicq-do-meta-user-update-security-confirm): New.
+ (eicq-do-meta-user-password): New.
+ (eicq-update-meta-info): New.
+
+ * eicq-setup.el: New.
+
+ * eicq-status.el (eicq-buddy-status-color-hint-flag): New.
+ (eicq-status-window-height): New.
+ (eicq-valid-statuses): New.
+ (eicq-user-initial-status): New.
+ (eicq-status-update-hook): New.
+ (eicq-face-online): New.
+ (eicq-face-away): New.
+ (eicq-face-occ): New.
+ (eicq-face-dnd): New.
+ (eicq-face-ffc): New.
+ (eicq-face-na): New.
+ (eicq-face-offline): New.
+ (eicq-statuses): New.
+ (eicq-status-face): New.
+ (eicq-status-bin): New.
+ (eicq-status-auto-reply): New.
+ (eicq-status-idle-reply): New.
+ (eicq-status-name): New.
+ (eicq-buddy-update-status): New.
+ (eicq-user-status): New.
+ (eicq-pack-status-change): New.
+ (eicq-do-status-update): New.
+ (eicq-change-status): New.
+ (eicq-status-buffer): New.
+ (eicq-status-show-buffer): New.
+
+ * eicq.el (eicq-meta): Removed.
+ (eicq-user-meta-nickname): Removed.
+ (eicq-user-meta-firstname): Removed.
+ (eicq-user-meta-lastname): Removed.
+ (eicq-user-meta-primary-email): Removed.
+ (eicq-user-meta-secondary-email): Removed.
+ (eicq-user-meta-old-email): Removed.
+ (eicq-auto-response-messages-p):
+ (eicq-valid-statuses): Removed.
+ (eicq-user-initial-status): Removed.
+ (eicq-new-message-hook): defvar -> defcustom
+ (eicq-status-window-height): Removed.
+ (eicq-read-message-hook): defvar -> defcustom
+ (eicq-user-status): Removed.
+ (eicq-system-message-hook): defvar -> defcustom
+ (eicq-status-update-hook): Removed.
+ (eicq-load-hook): New.
+ (eicq-monthnames): Removed.
+ (eicq-country-code): Removed.
+
+2002-10-01 Steve Youngs <youngs@xemacs.org>
+
+ * eicq-buddy.el: New file.
+
+ * eicq-log.el: New file.
+
+ * eicq-menu.el: New file.
+
+ * eicq-world.el: New file.
+
+ * eicq-v8proto.el: New file.
+
+ * eicq.el (eicq-log-*): Moved to eicq-log.el.
+ (eicq-buddy-*): Moved to eicq-buddy.el.
+ (eicq-*-menu): Moved to eicq-menu.el.
+ (eicq-*-map): Ditto.
+ (eicq-alias-*): Moved to eicq-world.el
+ (eicq-world-*): Ditto.
+
+ * eicq-report.el (eicq-report-debug): Add eicq-menu.el,
+ eicq-buddy.el, eicq-log.el eicq-world.el
+
+ * Makefile: Remove stuff concerning icq2tcp binary, we do it all
+ in lisp now.
+ (SOURCES): Add eicq-menu.el eicq-buddy.el eicq-log.el
+ eicq-world.el eicq-v8proto.el.
+
+2002-09-30 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-pack-login-a): New. The login is now a 2 stage
+ process so 'eicq-pack-login' has been split into -a & -b.
+ (eicq-pack-login-b): New.
+
+2002-09-29 Steve Youngs <youngs@xemacs.org>
+
+ * eicq-convert.el (eicq-import-from-micq): Support new micq rc
+ file format.
+
+2002-07-29 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-user-password): Move to eicq-comm.el
+ (eicq-connected-p): Ditto.
+ (eicq-network-mode): Ditto.
+ (eicq-network-kill): Ditto.
+
+2002-06-17 Steve Youngs <youngs@xemacs.org>
+
+ * Makefile (SOURCES): Add eicq-comm.el.
+
+2002-06-16 Jack Twilley <jmt@tbe.net>
+
+ * eicq.el (eicq-log-buddy-message): Made smileys optional.
+ (eicq-smiley): Created a configure variable in the
+ 'eicq-interface' group.
+
+2002-05-16 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-world-rc-regexp): Update regexp so we don't gobble
+ whitespace.
+ From Vladimir Alexiev <Vladimir@worklogic.com>.
+
+2002-05-12 Steve Youngs <youngs@xemacs.org>
+
+ * icq2tcp.c: Add a "This file is part of" clause.
+
+ * eicq-comm.el: Ditto.
+
+ * eicq-convert.el: Ditto.
+
+ * eicq-report.el: Ditto.
+
+ * eicq-toolbar.el: Ditto.
+
+ * eicq-wharf.el: Ditto.
+
+ * eicq.el (eicq-dropped-packet-counter): Moved to eicq-comm.el.
+ (eicq-resend-packet-counter): Ditto.
+ (eicq-recent-packet): Ditto.
+ (eicq-trimmed-packet-counter): Ditto.
+ (eicq-error-packets): Ditto.
+ (eicq-network): Ditto.
+ (eicq-bridge): Removed.
+ (eicq-connect): Moved to eicq-comm.el.
+ (eicq-main-map): We don't have "bridges" anymore, we use
+ "networks".
+ (eicq-main-menu): Ditto.
+ (eicq-bridge-mode): Renamed to 'eicq-network-mode'.
+ (eicq-bridge-kill): Removed.
+ (eicq-disconnect): Bridges are now networks.
+ (eicq-pack-login): Use the encrypted password from eicq-comm.el.
+ (eicq-hide-window): Bridges are now networks.
+ Add a "This file is part of" clause.
+
+2002-05-11 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-bridge-filename): Removed.
+ (eicq-bridge-buffer): Ditto.
+ (eicq-bridge-hostname): Ditto.
+ (eicq-bridge-port): Ditto.
+ (eicq-local-bridge-p): Ditto.
+
+ * eicq-comm.el: New file.
+
+ * eicq.el (eicq-comm): Require it.
+
+2002-04-10 Steve Youngs <youngs@xemacs.org>
+
+ * eicq-report.el (eicq-report-debug): Add eicq-comm.el.
+
+2002-02-17 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-version): Boost it up to version 0.5.0 as the
+ start of the ICQv7/8 series.
+ (eicq-server-hostname): Change to "login.icq.com".
+ (eicq-server-port): Change to 5190.
+
+2002-01-11 Steve Youngs <youngs@xemacs.org>
+
+ * TODO: Add items about PostgreSQL, X-Faces, Balloon-help
+ dialogs.
+
+2001-12-24 Steve Youngs <youngs@xemacs.org>
+
+ * TODO: Add item about implementing new protocol.
+
+2001-10-8 Thorsten Bonow <thorsten.bonow@post.rwth-aachen.de>
+
+ * icq2tcp.c (main): Assign command line arguments to variables
+ only after checking if correct number of them is passed to the
+ program. Cygwin segfaults when none existing arguments are
+ assigned.
+
+2001-09-29 Steve Youngs <youngs@xemacs.org>
+
+ * Version 0.2.17 released.
+
+2001-09-28 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-do-info): Prompt for a group to add a new user
+ to.
+
+2001-09-27 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-do-info): Check for blank or invalid nick-names
+ for 'eicq-add-user'. Prompt for an alternative.
+
+2001-09-25 Erik Arneson <erik@aarg.net>
+
+ * eicq-wharf.el (eicq-wharf-change-messages): If the Wharf buffer
+ hasn't been created, don't try to do anything.
+
+2001-09-26 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-status-bin): Send correct packet for web-aware so
+ 'eicq-user-meta-web-aware' works.
+
+2001-09-25 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-connect): Test for 'open' not 'run' in
+ process-status because it is a network stream.
+ (eicq-do-kicked-out): Don't try to auto-reconnect if
+ 'eicq-delete-offline-messages-flag' is set to "ask".
+ (eicq-add-user): New.
+ (eicq-add-user-p): New.
+ (eicq-new-buddy): New.
+ (eicq-new-uin): New.
+ (eicq-do-info): Handle doing a 'eicq-add-user'.
+ (eicq-add-new-user-to-buddy-buffer): New.
+ (eicq-do-search-end): Use it.
+
+2001-09-23 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-pack-search-by-uin): Changed to a defconst.
+ (eicq-search-by-uin): New.
+
+2001-09-18 Erik Arneson <erik@aarg.net>
+
+ * eicq.el (eicq-connect): Removed check for `eicq-bridge-port', as
+ some folks might want to set variable before running
+ `eicq-connect'. Besides, we're already checking
+ `eicq-bridge-local-p'.
+ (eicq-disconnect): Check to see if a symbol indicates a live
+ buffer before killing it.
+
+2001-09-19 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-logout): Reset counters in EicqWharf to zero.
+ (eicq-logout): Test for EicqWharf before trying to reset it.
+
+2001-09-17 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-logout): Do a 'eicq-world-update' and
+ 'eicq-send-contact-list' to reset the buddy buffer to it's
+ "pre-logged-in-state".
+
+2001-09-16 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-show-window): Emergency fix - I left out a
+ 'select-frame'.
+ (eicq-disconnect): Emergency fix - Uncomment something I'd
+ commented out for debugging purposes.
+ (eicq-do-kicked-out): Test for 'eicq-user-password', don't attempt
+ auto-reconnect if it's nil.
+
+2001-09-15 Steve Youngs <youngs@xemacs.org>
+
+ * Version 0.2.16 released.
+
+ * README: Add comments about EicqWharf and starting Eicq in a new
+ frame.
+
+ * eicq.el (eicq-save-log-on-exit-p): New.
+ (eicq-disconnect): Use 'eicq-save-log-on-exit-p'. And don't
+ prompt to save the buffer, just kill it.
+ (eicq-disconnect): Only delete the wharf frame if it's loaded.
+ (eicq-show-window): Create the wharf frame after all the other
+ Eicq buffers have been created, and then only if it's needed.
+ (eicq-do-meta-user-general): A little nicer output.
+
+2001-09-13 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el: Autoload 'eicq-wharf-new-frame' to kill off a
+ byte-compile warning.
+ (eicq-idle-reply): Set 'eicq-auto-reply-p' so we
+ auto-online when we should.
+
+2001-09-11 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-auto-reply): Use a modified subset of
+ 'eicq-send-message-helper' so the outgoing message doesn't get
+ logged. Instead use 'eicq-log-system "Automatic response sent."'
+ (eicq-idle-reply): Ditto.
+
+2001-09-07 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-do-kicked-out): Attempt auto-reconnect.
+
+2001-09-02 Steve Youngs <youngs@xemacs.org>
+
+ * eicq-report.el: Require 'message.
+
+ * eicq.el (eicq-face-online): Remove background colour to make it
+ look better for light backgrounds.
+ (eicq-face-away): Ditto.
+ (eicq-face-occ): Ditto.
+ (eicq-face-dnd): Ditto.
+ (eicq-face-ffc): Ditto.
+ (eicq-face-na): Ditto.
+ (eicq-face-offline): Ditto.
+ (eicq-face-log-unread): Ditto.
+ (eicq-face-log-read): Ditto.
+ (eicq-auto-response-messages-p): New.
+ (eicq-do-message-helper): Use 'eicq-auto-response-messages-p'.
+
+ * eicq-wharf.el (eicq-wharf-default-face): Remove background
+ colour to make it look better for light backgrounds.
+
+2001-08-18 Steve Youngs <youngs@xemacs.org>
+
+ * README: Minor updates.
+
+ * Makefile (SOURCES): Add eicq-wharf.el.
+
+ * eicq.el (eicq-show-window): Fire up the EicqWharf frame.
+ (eicq-disconnect): Kill the EicqWharf frame if present.
+
+ * eicq-wharf.el (eicq-wharf-frame-use-p): New.
+
+2001-08-18 Erik Arneson <erik@aarg.net>
+
+ * eicq-wharf.el: New file.
+
+2001-08-17 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-buddy-show-buffer): Remove the text "*** Bottom ***".
+ (eicq-sound-directory): Use 'locate-data-directory'.
+ (eicq-read-message-hook): New.
+ (eicq-system-message-hook): New.
+ (eicq-do-message-hook): Rename to 'eicq-new-message-hook'.
+ (eicq-do-status-update-hook): Rename to 'eicq-status-update-hook'.
+ (eicq-do-system-message): Use 'eicq-system-message-hook'.
+ (eicq-log-mark-read): Use 'eicq-read-message-hook' if called
+ interactively.
+ (eicq-idle-reply-away): New.
+ (eicq-idle-reply-na): New.
+ (eicq-status-idle-reply): New.
+ (eicq-idle-reply): New.
+ (eicq-do-message-helper): Use 'eicq-idle-reply'.
+ (eicq-do-info-ext): Hopefully, nicer layout for query results.
+ (eicq-do-info): Ditto.
+
+ * eicq-toolbar.el (eicq-icon-directory): Use
+ 'locate-data-directory.
+
+ * eicq-report.el: Require shadow and font-lock.
+ (eicq-report-bug-send-init): New.
+ (eicq-report-debug): Include checking eicq-report.el for changed
+ variables.
+ (eicq-prepare-report): Include load-path shadows, list of
+ installed XEmacs Packages and optionally the contents of the
+ user's init.el.
+ (eicq-report-post-hook): Force font-locking so the prompt for
+ a Subject isn't hidden with font-locking messages.
+
+
+2001-08-11 Steve Youngs <youngs@xemacs.org>
+
+ * Version 0.2.15 released.
+
+ * eicq-toolbar.el (eicq-use-toolbar): Change to customize group
+ 'eicq-interface'.
+
+ * eicq.el (eicq-start-in-new-frame): Change to customize group
+ 'eicq-interface'.
+
+ * INSTALL: Add comments about building on Solaris.
+
+2001-08-11 Jack Twilley <jmt@tbe.net>
+
+ * icq2tcp.c (main): Use 'perror' instead of 'herror' for Solaris
+ builds.
+
+ * Makefile: Make necessary changes for Solaris builds.
+
+2001-08-10 Erik Arneson <erik@aarg.net>
+
+ * eicq.el (eicq-show-window): Minor fix. Changed `framep' to
+ `frame-live-p' just in case the active frame has been destroyed
+ since we last used it.
+
+2001-08-11 Steve Youngs <youngs@xemacs.org>
+
+ * README: Change URLs to eicq.sf.net.
+ * TODO: Ditto.
+ * eicq-convert.el: Ditto.
+ * eicq.el: Ditto.
+ * icq2tcp.c: Ditto.
+
+2001-08-10 Erik Arneson <erik@aarg.net>
+
+ * eicq.el (eicq-local-bridge-p): New customize option. When
+ non-nil, Eicq will try to use a remote bridge. This should be
+ safer than trying to second guess ourselves by looking at various
+ variables.
+ (eicq-connect): Second try. This seems to work for both remote
+ and local bridges very nicely.
+
+2001-08-10 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-connect): Revert Erik's patch.
+ (eicq-auto-reply-p): New variable, if non-nil the auto-response
+ message won't automatically reset state to "online".
+ (eicq-do-message-helper): Use 'eicq-auto-reply-p'.
+ (eicq-send-message-helper): Ditto.
+ (eicq-auto-reply-away): Include shameless plug in auto-reply.
+ (eicq-auto-reply-occ): Ditto.
+ (eicq-auto-reply-dnd): Ditto.
+ (eicq-auto-reply-na): Ditto.
+
+2001-08-09 Erik Arneson <erik@aarg.net>
+
+ * eicq.el (eicq-frame): New variable. Keep track of EICQ's frame.
+ (eicq-show-window): Will now make sure that EICQ is redisplayed in
+ its preferred frame.
+ (eicq-disconnect): Reset the eicq-frame variable on disconnect,
+ when all of the buffers are killed and stuff. If
+ `eicq-start-in-new-frame' is non-NIL, it will delete the frame
+ that Eicq created during eicq-show-window.
+ (eicq-start-in-new-frame): New customize option. If non-NIL, Eicq
+ will start in its own frame.
+
+2001-08-09 Steve Youngs <youngs@xemacs.org>
+
+ * Makefile (CC): Change to 'gcc'.
+
+ * eicq.el (eicq-do-message-helper): Auto-response messages
+ now work.
+
+2001-08-08 Erik Arneson <erik@aarg.net>
+
+ * eicq.el (eicq-connect): Better support for remote icq2tcp
+ bridges.
+
+ * Makefile ($(BIN)): Fixed to compile icq2tcp.c instead of the C++
+ version. Woohoo!
+
+ * icq2tcp.c: Replacement for icq2tcp.cc. It's a direct port to C,
+ and now should compile pretty cleanly on FreeBSD and Linux.
+
+ * icq2tcp.cc: Removed. Obsolete! Kaput!
+
+2001-08-07 Erik Arneson <erik@aarg.net>
+
+ * Makefile (INFO_FILES): Changed.
+ ($(BIN)): New target to accurately reflect dependancies.
+ (.texi.info): Ditto!
+
+2001-08-07 Steve Youngs <youngs@xemacs.org>
+
+ * eicq-convert.el (eicq-import-from-licq): Autoload it.
+ Use '====' to take advantage of outline regexp of world-mode.
+ (eicq-import-from-micq): Ditto.
+
+2001-08-06 Erik Arneson <erik@aarg.net>
+
+ * eicq-convert.el (eicq-import-from-micq): Converts an MICQ
+ configuration to an EICQ 'world' file. I tried to get less
+ carried away -- this one has fewer lines! Imports these users
+ into the `micq' group.
+ (eicq-import-from-licq): Users are imported into the `licq' group.
+
+2001-08-07 Steve Youngs <youngs@xemacs.org>
+
+ * eicq-convert.el: require 'eicq.
+ (eicq-import-from-licq): Use 'eicq-world-rc-filename' in case
+ the user has their world file in a different place from the default.
+ Remove 'buf' variable, it's not used. Did somebody get a little
+ carried away? :-)
+
+ * Makefile (SOURCES): Add eicq-convert.el
+
+2001-08-06 Erik Arneson <erik@aarg.net>
+
+ * eicq-convert.el: New File.
+ (eicq-import-from-licq): New. Converts an LICQ configuration to
+ an EICQ 'world' file.
+
+2001-08-02 Thorsten Bonow <thorsten.bonow@post.rwth-aachen.de>
+
+ * Makefile: Add program locations/path for Windows/Cygwin.
+
+ * eicq-user-install.sh: ditto.
+
+ * INSTALL: Add Windows/Cygwin Installation instructions.
+
+2001-07-22 Steve Youngs <youngs@xemacs.org>
+
+ * Version 0.2.14 released.
+
+ * eicq-toolbar.el (eicq-help-icon): New.
+ (eicq-toolbar-help): New.
+ (eicq-log-toolbar): Use them.
+
+ * eicq.texi: Still not finished, but some progress has been
+ made. :-)
+
+2001-07-19 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-disconnect): Update doc string.
+
+2001-07-16 Steve Youngs <youngs@xemacs.org>
+
+ * Makefile (BIN): Rename udp2tcp to icq2tcp.
+ (BIN_DIR): Change to lib-src.
+ (STAGING): New.
+ (BIN_STAGING): New.
+ (DATA_STAGING): New.
+ (INFO_STAGING): New.
+ (LISP_STAGING): New.
+ (TAR): New.
+ (TAR_FLAGS): New.
+ (VER): New.
+ (pkg): New target.
+
+ * udp2tcp.cc: Removed.
+
+ * icq2tcp.cc: New file, at this stage it is a direct copy
+ of udp2tcp.cc.
+
+ * eicq.el: Use icq2tcp throughout instead of udp2tcp.
+ (eicq-bridge-filename): Don't use a path, XEmacs can find it providing
+ it's in the XEmacs exec path.
+
+
+2001-06-06 Steve Youngs <youngs@xemacs.org>
+
+ * eicq-report.el (eicq-report-debug): New.
+ (eicq-prepare-report): Use it.
+
+2001-06-05 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-version): Add optional arg so you can insert the
+ version string at point. Autoload it.
+ (eicq-user-meta-web-aware): Type boolean.
+ (eicq-user-meta-hide-ip): Ditto.
+ (eicq-user-meta-authorization): Ditto.
+ (eicq-log-info-mark): Ditto.
+ (eicq-log-buddy-status-mark): Ditto.
+ (eicq-log-buddy-message-mark): Ditto.
+ (eicq-log-outgoing-mark): Ditto.
+ (eicq-log-error-mark): Ditto.
+ (eicq-log-debug-mark): Ditto.
+ (eicq-log-system-mark): Ditto.
+ (eicq-buddy-status-color-hint-flag): Ditto.
+
+ Most user variables moved to take advantage of new bug-report
+ code.
+
+2001-06-03 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-user-meta-birth-year): Format for this variable
+ should be YY, update doc accordingly.
+
+2001-05-31 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-pack-keep-alive-1): Remove - obsolete.
+ (eicq-pack-info-request): Ditto.
+ (eicq-pack-info-ext-request): Ditto.
+ (eicq-pack-update-info): Ditto.
+ (eicq-pack-update-info-ext): Ditto.
+
+2001-05-20 Steve Youngs <youngs@xemacs.org>
+
+ * Makefile (superupgrade): Make sure owner/group is set correctly
+ in source tree.
+
+ * eicq.texi: Finally started to write this. Not finished yet,
+ but maybe by the end of the weekend.
+
+ * eicq.el (eicq-log-buddy-message): Switch to log buffer for smileys.
+ (eicq-auto-away-timeout-set): Use a 2nd itimer so auto na works
+ properly.
+
+ * etc/eicq/world: Updated. Somehow it got overwritten with an old
+ version of itself.
+
+2001-05-07 Steve Youngs <youngs@xemacs.org>
+
+ * Makefile (superupgrade): New target for me only.
+
+ * eicq.el (eicq-buddy-show-buffer): Remove "*** Contacts ***".
+ (eicq-auto-away-timeout-set): Typo.
+ (eicq-interface): New customize group.
+ (eicq-hide-window): Add eicq-status-window.
+
+2001-05-05 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-status-show-buffer): Change name of buffer to "*Status*".
+
+2001-05-02 Steve Youngs <youngs@xemacs.org>
+
+ * Makefile (AUTO_PRELOADS): New.
+
+2001-04-28 Steve Youngs <youngs@xemacs.org>
+
+ * Version 0.2.13 released.
+
+ * eicq.el (eicq-message-sound): Removed, put into alist.
+ (eicq-chat-sound): Ditto.
+ (eicq-url-sound): Ditto.
+ (eicq-buddy-sound): Ditto.
+ (eicq-auth-sound): Ditto.
+ (eicq-emailx-sound): Ditto.
+ (eicq-pager-sound): Ditto.
+ (eicq-sound-alist): New.
+ (eicq-use-sound-flag): New.
+ (eicq-do-message-helper): Use 'eicq-sound-alist', 'eicq-use-sound-flag'.
+ (eicq-do-online): Ditto.
+ (eicq-log-buddy-message): Run 'smiley-buffer' and 'goto-address'.
+
+
+2001-04-22 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-buddy-show-buffer): Rename and rearrange status widgets.
+ (eicq-status-window-height): New.
+ (eicq-status-buffer): New.
+ (eicq-status-show-buffer): New.
+ (eicq-show-window): Show the status buffer as well.
+ (eicq-disconnect): Kill the status buffer.
+ (eicq-switch-to-buddy-buffer): New.
+
+ * eicq-toolbar.el: Reduced the number of tools on the toolbar.
+
+2001-04-21 Steve Youngs <youngs@xemacs.org>
+
+ * Version 0.2.12 released.
+
+ * eicq-toolbar.el (eicq-toolbar-disconnect): Do 'eicq-logout' before
+ 'eicq-disconnect'.
+ (eicq-buddy-toolbar): Remove. Use the same toolbar for both the
+ buddy and log buffers.
+ (eicq-install-buddy-toolbar): Use the log toolbar.
+
+ * eicq.el (eicq-do-login-confirm): Run 'eicq-show-window'.
+ (eicq-disconnect): Kill the Eicq buffers.
+ (eicq-log-mode): Load both the log menu and the buddy menu.
+ (eicq-buddy-mode): Ditto.
+
+2001-04-01 Steve Youngs <youngs@xemacs.org>
+
+ * README: Added section about submitting patches.
+
+2001-03-21 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-log-next-unread): Make it interactive.
+ (eicq-log-previous-unread): Ditto.
+
+2001-03-19 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-log-mode-map): 'n' & 'p' are now next and previous
+ Unread messages. 'N' & 'P' are for next and previous message.
+ Mark unread has been moved to 'v'.
+ (eicq-buddy-show-buffer): Add widgets for changing status via the
+ buddy buffer.
+
+2001-03-18 Jack Twilley <jmt@tbe.net>
+
+ * eicq.el (eicq-log-next-unread): New.
+ (eicq-log-previous-unread): New.
+
+2001-03-12 Jack Twilley <jmt@tbe.net>
+
+ * eicq.el (eicq-user-auto-away-p): New variable.
+ (eicq-auto-away-timeout-set): Use new variable, change docstring.
+ Reordered away tests.
+ (eicq-send-message-helper): Use new variable.
+ (eicq-change-status): Use new variable.
+ (eicq-log-*-mark): New variables.
+ (eicq-log-*): Use new variables.
+ (eicq-log-buffer-position-flag): New variable.
+ (eicq-log-entry-re): New variable.
+ (eicq-log): Use new variables, change docstring.
+ (eicq-buddy-update-status): Only display status packet if status
+ has changed.
+
+2001-03-09 Steve Youngs <youngs@xemacs.org>
+
+ * Version 0.2.11 released.
+
+ * eicq.el (eicq-blurb): Update.
+ (eicq-do-offline-message): Remove require 'timezone and move
+ it to top of file.
+
+ * eicq-report.el (eicq-prepare-report): New.
+ (reporter-version): Remove.
+ (vars): Ditto.
+ (reporter-confirm-p): Ditto.
+ (reporter-package-abbrev): Ditto.
+ (eicq-report-other-vars): Ditto.
+ (eicq-report-avoid-vars): Ditto.
+ (eicq-report-get-versions): Ditto.
+ (eicq-report-get-user-vars): Ditto.
+ (eicq-gnus-submit-report): Ditto.
+ (eicq-report-bug): Don't use reporter.el.
+
+ * eicq-toolbar.el (eicq-icon-directory): Make it customizable.
+
+2001-03-06 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el: (eicq-delete-offline-messages-flag): Change default to 'ask.
+
+2001-03-06 Steve Youngs <youngs@xemacs.org>
+
+ * Version 0.2.10 released.
+
+ * eicq.el: Re-arrange variables and constants for a clean build.
+ (eicq-version): Increment.
+ (eicq-bridge-filename): Change default to /usr/local/bin/udp2tcp
+ (eicq-browse-homepage): Autoload it.
+
+ * eicq-user-install.sh (RCFILE): Change default to
+ /usr/local/lib/xemacs/site-packages/etc/eicq/world.
+
+ * eicq-report.el: Update doc strings.
+
+ * eicq-toolbar.el: Ditto.
+ (eicq-icon-directory): Change default to
+ /usr/local/lib/xemacs/site-packages/etc/eicq/
+
+ * infohack: New file.
+
+ * README: Update URL.
+
+ * INSTALL: Updated to reflect not being an XEmacs Package.
+
+ * Makefile: Complete re-write to use standard 'make', 'make install'.
+
+2001-03-02 Steve Youngs <youngs@xemacs.org>
+
+ * Makefile: Re-shuffle the order of the variables so everything
+ gets installed properly. This supercedes the change I made earlier.
+
+ * INSTALL: Update.
+
+ * NEWS: Ditto.
+
+ * TODO: Ditto.
+
+ * Makefile (ELCS): Add eicq-report.elc.
+ (include ../../XEmacs.rules): Move to below other variables so
+ everything gets installed properly.
+
+ * eicq-toolbar.el: Add require 'eicq.
+
+2001-03-01 Steve Youngs <youngs@xemacs.org>
+
+ * Makefile (REQUIRES): Add eicq, gnus.
+
+ * eicq.el (eicq-blurb): New
+ (eval-when-compile): Remove require 'eicq-report.
+
+ * udp2tcp.cc (main): Update URL.
+
+2001-02-28 Ben Wing <ben@xemacs.org>
+
+ * udp2tcp.cc (main): Conditionalize change to third arg to accept
+ on __CYGWIN__, so that all other systems keep size_t -- simply
+ changing the arg makes this not compile under Linux.
+
+2001-02-24 Ben Wing <ben@xemacs.org>
+
+ * Makefile (STRIP):
+ * Makefile (EXTRA_SOURCES):
+ * Makefile (EXTRA_OBJS):
+ Fix udp2tcp compilation to work under MS Windows.
+
+ * udp2tcp.cc (main):
+ Emergency fixes so it compiles. (change bzero to memset; fix type
+ of third arg to accept)
+
+2001-03-01 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-main-menu): Capitalise entries.
+ (eicq-log-menu): Ditto.
+
+2001-02-21 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el: Update all doc strings.
+ (eicq-email-author): Move to eicq-report.el
+
+ * eicq-report.el: New file.
+
+2001-01-25 Steve Youngs <youngs@xemacs.org>
+
+ * version 0.2.8 released - XEmacs package 1.03
+
+ * eicq.el (eicq-buddy-view): Remove :set 'eicq-buddy-view-set.
+ (eicq-version): Increment.
+
+ * eicq.texi (VERSION): Ditto.
+
+2000-11-27 Steve Youngs <youngs@xemacs.org>
+
+ * Makefile (CFLAGS): Add -static so people that use a different
+ compiler to me wont have problems.
+
+2000-11-14 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el: Doc fix.
+
+2000-10-23 Steve Youngs <youngs@xemacs.org>
+
+ * version 0.2.7 released - XEmacs package 1.02
+
+ * *: Update my email address.
+
+2000-10-05 Martin Buchholz <martin@xemacs.org>
+
+ * *: Mega typo fix.
+
+2000-08-22 Steve Youngs <youngs@xemacs.org>
+
+ * Makefile (EXTRA_OBJS): New variable.
+
+2000-08-16 Steve Youngs <youngs@xemacs.org>
+
+ * version 0.2.6 released - XEmacs package 1.01
+
+ * etc/world: added info about adding your own UIN
+
+ * INSTALL: ditto
+
+ * INSTALL: fixed typo
+
+2000-08-15 Steve Youngs <youngs@xemacs.org>
+
+ * verion 0.2.5 released - XEmacs package 1.00
+
+ * package-info-in: changed description
+
+2000-07-18 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.texi: new file
+
+ * INSTALL: total re-write for XEmacs packages
+
+ * package-info.in: new file
+
+ * eicq-toolbar.el: updated license
+
+ * eicq.el: updated license
+
+ * Makefile: total re-write for XEmacs packages
+
+2000-06-26 Steve Youngs <youngs@xemacs.org>
+
+ * README: moved install stuff to INSTALL
+
+ * INSTALL: new file
+
+ * world: my UIN was wrong :-( fixed
+
+2000-06-07 Steve Youngs <youngs@xemacs.org>
+
+ * version 0.2.4 released
+
+ * README: updated install instructions
+
+2000-06-06 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-buddy-mode-hook): add-hook
+ eicq-install-buddy-toolbar
+ (eicq-log-mode-hook): add-hook eicq-install-log-toolbar
+ (eicq-email-author): change address
+
+ * Makefile: updated for a more "system-wide" install
+
+ * eicq-user-install.sh: New file
+
+ * eicq-toolbar.el: New file
+
+2000-06-05 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-do-message-helper): added new sounds
+ (eicq-do-message-helper): pager now decodes message
+ (eicq-auth-sound): New variable
+ (eicq-emailx-sound): New variable
+ (eicq-pager-sound): New variable
+ (eicq-global-map-set): new key bindings added to eicq-buddy-map
+ and eicq-log-map
+
+2000-06-01 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el (eicq-main-menu): "Update Meta Info" pointed to
+ the wrong place. Now points to eicq-update-meta-info
+
+2000-05-30 Steve Youngs <youngs@xemacs.org>
+
+ * version 0.2.3 released
+
+2000-05-13 Steve Youngs <youngs@xemacs.org>
+
+ * eicq.el
+ (eicq-sound): New customization group
+ (eicq-sound-directory): New variable
+ (eicq-message-sound): New variable
+ (eicq-chat-sound): New variable
+ (eicq-url-sound): New variable
+ (eicq-buddy-sound): New variable
+
+1999-08-12 Stephen Tse <stephent@sfu.ca>
+
+ * version 0.2.2 released
+
+ * eicq.el
+ (eicq-world-update): extent for alias (from Erik)
+ (eicq-log-buddy-url): new function, extent for url (from Erik)
+ (eicq-url-map): new variable
+ (eicq-alias-map): new variable
+ (eicq-send-message-via-mouse): new function
+ (eicq-send-message-alias-here-via-mouse): removed
+ (world-mode): new mode and world-* helper
+ (world-find): new function
+ (world-sort): new function
+ (eicq-change-user): new function
+ (eicq-buddy-view-connected): update eicq-buddy-view
+ (eicq-status-bin): zero-padded
+ (eicq-bridge-buffer): store buffer id instead of name
+ (eicq-hide-window): new function
+ (eicq-email-author): carbon-copy to mailing list
+
+ * world: add sample records
+
+1999-07-10 Stephen Tse <stephent@sfu.ca>
+
+ * version 0.2.1 released.
+
+ * eicq.el
+ (eicq-do-kicked-out): remove relogin
+ (eicq-log-around): fixed to include first line
+ (eicq-do-message-helper): display authorization message
+ (eicq-bridge-mode): fixed kill-buffer-query-functions
+
+1999-06-29 Stephen Tse <stephent@sfu.ca>
+
+ * version 0.2.0 released.
+ - ICQ version 5 protocol
+ - outgoing delay queue and resent queue
+ - meta user info query and update
+
+ * eicq.el
+ (eicq-log-mark-*): mark all log in a region
+ (eicq-keep-alive-stop): use start-itimer
+ (eicq-pack-contact-list): use smaller packet
+ (eicq-do-message-helper): receive contact list transfer
+ (eicq-register-new-user): new function
+ (eicq-do-info-ext): fixed age bug
+ (eicq-world-update): RC file not closed if current or modified
+ (eicq-auto-away-timeout-set): added auto-na
+ (eicq-bin-alias): optional from
+ (eicq-alias-around): cleaned up
+ (eicq-log-around): new function
+ (eicq-send-message): encode only outgoing part
+ (eicq-forward-message-around): new function
+ (eicq-change-status): allow only valid statues
+ (eicq-logout): clear buddy buffer when offline
+ (eicq-change-status): change only if different
+ (eicq-valid-packet-p): integrated into eicq-do
+ (eicq-ack-alist): removed
+ (eicq-ack): integrated into eicq-do
+ (eicq-pack-login): fixed initial status
+ (eicq-relogin): fixed relogin initial status
+ (eicq-query-info): skip nil local info
+
+ - more debugging and profiling counters
+ eicq-dropped-packet-counter
+ eicq-resend-packet-counter
+ eicq-auto-relogin-counter
+
+ * README: split into readme.developer
+ * README.developer: new
+ * udp2tcp.cc: protocol version 5
+
+1999-06-16 Stephen Tse <stephent@sfu.ca>
+
+ * version 0.1.3 released.
+
+ * eicq.el
+ (eicq-spliter): new function
+ (eicq-send-message): send long messages
+ (eicq-do-info): fixed authorization check
+ (eicq-pack-update-info): new function
+ (eicq-do-search-end): new function
+ (eicq-auto-na-timeout-set): new function
+ (eicq-current-seq-num): follow micq, start from 0 instead of 1
+ (eicq-do-kicked-out): graceful relogin
+ (eicq-login): login only when offline
+ (eicq-buddy-getf): new function
+ (eicq-buddy-putf): new function
+ (eicq-int-byte): new function
+ (eicq-network-separator): eicq-trimmed-packet
+ (eicq-pack-contact-list): fixed random uin
+ (eicq-network-filter): fixed bug in checking validity of packets
+ (eicq-do-message-hook): new variable
+ (eicq-do-status-update-hook): new variable
+ (eicq-hex-bin): downcase uppercase
+ (eicq-process-alias-input): new function
+
+ : select
+ (eicq-group-select-aliases)
+ (eicq-select-alias-around)
+ (eicq-buddy-select-all-in-view)
+ (eicq-buddy-select-all-in-view-by-status)
+ (eicq-buddy-select-all-in-view-by-regexp)
+ (eicq-buddy-selected-in-view)
+ (eicq-select-alias-here)
+
+ : use length prefix instead of delimiting magic string
+ - (eicq-redo-hex)
+ - (eicq-network-filter)
+ - (eicq-network-separator)
+ - (eicq-send)
+ - (eicq-magic-string)
+
+ * README
+ : updated for new resource file
+ : fixed wrong assumption about eicq-pack-contact-list
+
+ * udp2tcp.cc (debug_socket):
+ : use length prefix instead of delimiting magic string
+ : remove usleep
+
+1999-06-01 Stephen Tse <stephent@sfu.ca>
+
+ * version 0.1.2 released.
+
+ * eicq.el:
+ - add `encode/decode-coding-string'
+
+1999-05-22 Stephen Tse <stephent@sfu.ca>
+
+ * eicq.el:
+ (eicq-send-contact-list): make interactive
+ (eicq-main-menu): add "Resend contact list"
+
+1999-05-18 Stephen Tse <stephent@sfu.ca>
+
+ * Makefile: brand new from Erik Arneson <erik@mind.net>
+
+ * README:
+ - change installation steps for new Makefile
+ - mention mailing list and `eicq-log-new-file' in tips
+
+ * eicq.el: merge patches from Erik Arneson <erik@mind.net>
+ - add confirmation for sending blank message/url
+ - `eicq-send-message-alias-here-via-mouse'
+ - `browse-url-at-point' and other key bindings
+
+ * eicq.el (eicq-message-types): one byte instead of two
+
+1999-05-12 Stephen Tse <stephent@sfu.ca>
+
+ * version 0.1.1 released.
+
+1999-05-12 Stephen Tse <stephent@sfu.ca>
+
+ * version 0.1 released.
+
--- /dev/null
+# do not edit -- automatically generated by arch changelog
+# non-id: automatic-ChangeLog--steve@eicq.org--2004/eicq--main--0.6
+#
+
+2004-11-22 21:56:38 GMT Steve Youngs <steve@eicq.org> patch-15
+
+ Summary:
+ Minor fix to donation code
+ Revision:
+ eicq--main--0.6--patch-15
+
+ * eicq.el (eicq-donation): Test for featurep 'png and 'jpeg before trying
+ to display the glyphs.
+
+
+ modified files:
+ eicq.el
+
+
+2004-11-22 16:30:22 GMT Steve Youngs <steve@eicq.org> patch-14
+
+ Summary:
+ Attempt to generate some donations
+ Revision:
+ eicq--main--0.6--patch-14
+
+ * eicq.el (eicq-donation-notice): New. Shameless appeal for cash.
+ (eicq-paypal-glyph): New. A button to use in the "donation" buffer.
+ (eicq-maybe-later-glyph): Ditto.
+ (eicq-make-donation): New. For when the user takes pity on us and
+ decides to donate to the project.
+ (eicq-no-donation): New. For when they don't.
+ (eicq-donation-map): New. Keymap for the extents in the "donation"
+ buffer.
+ (eicq-nodonation-map): Ditto.
+ (eicq-donation): New. Function to create the "donation" buffer.
+
+ * eicq-menu.el (eicq-main-menu): Add a menu item for `eicq-donation'.
+
+
+ modified files:
+ eicq-menu.el eicq.el
+
+
+2004-11-21 21:17:55 GMT Steve Youngs <steve@eicq.org> patch-13
+
+ Summary:
+ Bitrot removal (20.4 compat code... sheesh)
+ Revision:
+ eicq--main--0.6--patch-13
+
+ * eicq.el (encode-coding-string): Removed. Compatibility with
+ 20.4... you've gotta be kidding!
+ (decode-coding-string): Ditto.
+
+
+ modified files:
+ eicq.el
+
+
+2004-11-15 15:35:58 GMT Steve Youngs <steve@eicq.org> patch-12
+
+ Summary:
+ Minor build fix.
+ Revision:
+ eicq--main--0.6--patch-12
+
+ * eicq.el (eicq-pack-login-a): Removed. Left over crud from
+ eicq-v8proto.el.
+ (eicq-pack-login-b): Ditto.
+
+
+ modified files:
+ eicq.el
+
+
+2004-11-15 15:32:18 GMT Steve Youngs <steve@eicq.org> patch-11
+
+ Summary:
+ require eicq-v8 instead of eicq-v8proto
+ Revision:
+ eicq--main--0.6--patch-11
+
+
+ modified files:
+ eicq-comm.el
+
+
+2004-11-15 15:28:14 GMT Steve Youngs <steve@eicq.org> patch-10
+
+ Summary:
+ Final sf.net -> eicq.org renaming.
+ Revision:
+ eicq--main--0.6--patch-10
+
+ * .arch-inventory: Make eicq-version.texi precious
+
+ * INSTALL: Update the URLs mentioned and slightly re-word it.
+
+ * README: Ditto.
+
+ * TODO: Update URLs
+
+ * eicq.texi: Ditto.
+ Include generated file eicq-version.texi
+
+ * Makefile (texinfo): Add eicq-version.texi
+ (eicq-version.el): Test to see if tla is present and
+ executable before using it to generate version info.
+ (eicq-version.texi): New. Generated file containing version
+ info for eicq.info.
+ (distclean): Remove eicq-version.texi too.
+ (.PHONY): Add eicq-version.texi.
+
+ * eicq-v8proto.el: Removed. Obsolete, replaced by eicq-v8.el
+
+
+ This should be the last of the "sf.net -> eicq.org" renaming. There is
+ also some minor updates to INSTALL/README... slight re-wording and
+ re-organisation.
+
+ The version string that goes into eicq.info is now generated at build
+ time in the same manner as it is for the lisp.
+
+ removed files:
+ .arch-ids/eicq-v8proto.el.id eicq-v8proto.el
+
+ modified files:
+ .arch-inventory INSTALL Makefile README TODO eicq.texi
+
+
+2004-11-15 05:49:30 GMT Steve Youngs <steve@eicq.org> patch-9
+
+ Summary:
+ Fix `eicq-update-world'
+ Revision:
+ eicq--main--0.6--patch-9
+
+ * eicq-world.el (eicq-world-update): Convert UINs to numbers.
+ (world-mode): Remove some old crud about highlighting dates.
+ Don't put it into outline-mode.
+
+ `world-mode' used to put the rc file (where the contact list is kept)
+ into outline-mode, but for some reason it is throwing a `keymapp nil'
+ error. So I've disabled that "feature" for the time being. I've added a
+ "FIXME" comment to eicq-world.el so we can come back to it some time in
+ the future.
+
+
+ modified files:
+ eicq-world.el
+
+
+2004-11-15 04:47:05 GMT Steve Youngs <steve@eicq.org> patch-8
+
+ Summary:
+ Build fixes.
+ Revision:
+ eicq--main--0.6--patch-8
+
+ * eicq-v8.el (eicq-v8-snac-srv-recv-msg): Remove unused variable
+ `test-tlvs'.
+
+ * eicq.el: Bump version in file header.
+ (require): eicq-v8 instead of eicq-v8proto.
+ (eicq-login): Remove argument `password'.
+
+ Remove all of the now useless CVS keyword headers from all files.
+
+ This patch returns us back to the land of clean builds.
+
+ modified files:
+ eicq-buddy.el eicq-comm.el eicq-convert.el eicq-log.el
+ eicq-menu.el eicq-meta.el eicq-report.el eicq-setup.el
+ eicq-status.el eicq-toolbar.el eicq-v8.el eicq-v8proto.el
+ eicq-wharf.el eicq-world.el eicq.el eicq.texi
+
+
+2004-11-15 02:35:19 GMT Steve Youngs <steve@eicq.org> patch-7
+
+ Summary:
+ Update the bug reporter
+ Revision:
+ eicq--main--0.6--patch-7
+
+ * eicq-report.el (eicq-bug-address): Use eicq-bugs@eicq.org as the
+ address to send bug reports to.
+ (eicq-report-pre-hook): Don't include the version string in the bug
+ report subject header because it is way too long now.
+ (eicq-prepare-report): Put the list of altered Eicq variables at the
+ top of the report where they can be seen easily.
+ (eicq-email-salutations): Typo fix.
+ (eicq-prepare-email-author): Update Cc address to be
+ eicq-users@eicq.org.
+ Don't put the version string in the subject header because it is too
+ long now. Put it in the body instead.
+ (eicq-report-debug): This doesn't need to be interactive.
+
+
+ modified files:
+ eicq-report.el
+
+
+2004-11-14 02:03:57 GMT Steve Youngs <steve@eicq.org> patch-6
+
+ Summary:
+ Build fix -- Work around broken smiley.el
+ Revision:
+ eicq--main--0.6--patch-6
+
+ * Makefile (PRELOADS): ignore `executable-find'.
+
+ The "XEmacs-unfriendly" version of smiley.el from gnus.org requires
+ executable-find via nnheader.el via about 6 other libs via
+ gnus-encrypt.el.
+
+ The "XEmacs-friendly" version of smiley.el, the one that is in the XEmacs
+ package version of Gnus, the superior-to-the-gnu-version by Wes Hardaker,
+ does not require nnheader and so doesn't need executable-find.
+
+ This patch makes it possible for the people with the broken smiley.el to
+ build Eicq.
+
+
+ modified files:
+ Makefile
+
+
+2004-11-12 03:53:23 GMT Steve Youngs <steve@eicq.org> patch-5
+
+ Summary:
+ Switch to a tla style version string.
+ Revision:
+ eicq--main--0.6--patch-5
+
+ * Makefile (VER): Bump to 0.6
+ (eicq-version.el): New.
+ (all): Use it.
+ (version): Convenience target - alias for `eicq-version.el'.
+ (distclean): Also remove eicq-version.el.
+ (.PHONY): New.
+ (EXTRA_SRC): Remove `ChangeLog'.
+
+ * .arch-inventory: New. Make all the generated files precious.
+
+ * eicq.el (eicq-version): Removed. This comes from eicq-version.el now
+ so require that.
+
+ new files:
+ .arch-ids/.arch-inventory.id .arch-inventory
+
+ modified files:
+ Makefile eicq.el
+
+
+2004-11-12 03:14:32 GMT Steve Youngs <steve@eicq.org> patch-4
+
+ Summary:
+ Minor build fix
+ Revision:
+ eicq--main--0.6--patch-4
+
+ * eicq.el (eicq-auto-away-timeout): Move this to after
+ `eicq-auto-away-timeout-set'.
+
+ I got over zealous and should not have moved this defcustom in the last
+ patch. This just reverts that part of it.
+
+ modified files:
+ eicq.el
+
+
+2004-11-11 06:56:21 GMT Steve Youngs <steve@eicq.org> patch-3
+
+ Summary:
+ Minor fixes/adjustments to Evgeny's previous patch
+ Revision:
+ eicq--main--0.6--patch-3
+
+ Global replace `income' => `incoming'
+ Global replace `outcome' => `outgoing'
+
+ Fix a couple of typos and move a couple of defcustoms to where the
+ bug-reporter will pick them up.
+
+ modified files:
+ eicq-v8.el eicq.el
+
+
+2004-11-10 12:46:48 GMT Steve Youngs <steve@eicq.org> patch-2
+
+ Summary:
+ v8 protocol integration
+ Revision:
+ eicq--main--0.6--patch-2
+
+ 2004-11-09 Zajcev Evgeny <zevlg@yandex.ru>
+
+ * eicq-v8.el (eicq-v8-version): New.
+ (eicq-FLAP-HELLO): Removed.
+ (eicq-FLAP-SNAC): Removed.
+ (eicq-FLAP-ERRORS): Removed.
+ (eicq-FLAP-LOGOFF): Removed.
+ (eicq-FLAP-PING): Removed.
+ (eicq-FLAP-VER-MAJOR): Removed.
+ (eicq-FLAP-VER-MINOR): Removed.
+ (eicq-FLAP-VER-LESSER): Removed.
+ (eicq-FLAP-VER-BUILD): Removed.
+ (eicq-FLAP-VER-SUBBUILD): Removed.
+ (eicq-v8-FLAP-HELLO): New.
+ (eicq-v8-FLAP-SNAC): New.
+ (eicq-v8-FLAP-ERRORS): New.
+ (eicq-v8-FLAP-LOGOFF): New.
+ (eicq-v8-FLAP-PING): New.
+ (eicq-v8-FLAP-VER-MAJOR): New.
+ (eicq-v8-FLAP-VER-MINOR): New.
+ (eicq-v8-FLAP-VER-LESSER): New.
+ (eicq-v8-FLAP-VER-BUILD): New.
+ (eicq-v8-FLAP-VER-SUBBUILD): New.
+ (eicq-v8-message-types): New.
+ (eicq-v8-valid-income-handlers): New.
+ (eicq-v8-valid-outcome-handlers): New.
+ (eicq-ctx): Removed.
+ (eicq-v8-ctx): New.
+ (eicq-ctx-get-prop): Removed.
+ (eicq-v8-ctx-get-prop): New.
+ (eicq-ctx-put-prop): Removed.
+ (eicq-v8-ctx-put-prop): New.
+ (eicq-ctx-rm-prop): Removed.
+ (eicq-v8-ctx-rm-prop): New.
+ (eicq-v8-ctx-get-income-handlers): New.
+ (eicq-default-ctx): Removed.
+ (eicq-v8-ctx-add-income-handler): New.
+ (eicq-v8-ctx-del-income-handler): New.
+ (eicq-v8-ctx-run-income-handler): New.
+ (eicq-v8-default-ctx): New.
+ (eicq-connections): Removed.
+ (eicq-v8-connections): New.
+ (eicq-v8-debug): New.
+ (eicq-flap-cid): Removed.
+ (eicq-v8-flap-cid): New.
+ (eicq-flap-seq): Removed.
+ (eicq-v8-flap-seq): New.
+ (eicq-flap-data): Removed.
+ (eicq-v8-flap-data): New.
+ (eicq-snac-family): Removed.
+ (eicq-v8-snac-family): New.
+ (eicq-snac-subtype): Removed.
+ (eicq-v8-snac-subtype): New.
+ (eicq-snac-flags0): Removed.
+ (eicq-v8-snac-flags0): New.
+ (eicq-snac-flags1): Removed.
+ (eicq-v8-snac-flags1): New.
+ (eicq-connect): Removed.
+ (eicq-v8-create-ctx): New.
+ (eicq-snacrid): Removed.
+ (eicq-v8-snacrid): New.
+ (eicq-tlv-type): Removed.
+ (eicq-v8-tlv-type): New.
+ (eicq-v8-connect): New.
+ (eicq-tlv-val): Removed.
+ (eicq-v8-tlv-len): New.
+ (eicq-v8-tlv-val): New.
+ (eicq-v8-tlv-str): New.
+ (eicq-v8-tlv-num): New.
+ (eicq-util-encrypt): Removed.
+ (eicq-v8-util-encrypt): New.
+ (eicq-close): Removed.
+ (eicq-v8-close): New.
+ (eicq-send): Removed.
+ (eicq-v8-send): New.
+ (eicq-send-flush): Removed.
+ (eicq-v8-send-flush): New.
+ (eicq-send-recv): Removed.
+ (eicq-v8-send-recv): New.
+ (eicq-proc-find): Removed.
+ (eicq-v8-proc-find): New.
+ (eicq-proc-sentinel): Removed.
+ (eicq-v8-proc-sentinel): New.
+ (eicq-proc-filter): Removed.
+ (eicq-v8-proc-filter): New.
+ (eicq-v8-snacv-list): New.
+ (eicq-v8-snac-list): New.
+ (eicq-v8-recv-message): New.
+ (eicq-v8-snac-srv-fromicqsrv): New.
+ (eicq-v8-snac-srv-set-interval): New.
+ (eicq-v8-snac-srv-reply-icbm): New.
+ (eicq-v8-snac-srv-replyinfo): New.
+ (eicq-v8-snac-srv-reply-buddy): New.
+ (eicq-v8-snac-srv-reply-location): New.
+ (eicq-v8-snac-srv-families): New.
+ (eicq-v8-snac-srv-families2): New.
+ (eicq-v8-snac-srv-rates): New.
+ (eicq-v8-snac-srv-motd): New.
+ (eicq-v8-snac-srv-recv-msg): New.
+ (eicq-v8-snac-srv-err): New.
+ (eicq-v8-snac-srv-reply-bos): New.
+ (eicq-proc-process-incoming): Removed.
+ (eicq-v8-snac-cli-setuserinfo): New.
+ (eicq-v8-status-alist): New.
+ (eicq-v8-snac-cli-setstatus): New.
+ (eicq-v8-snac-cli-add-contact): New.
+ (eicq-v8-snac-cli-keepalive): New.
+ (eicq-v8-create-meta-snac): New.
+ (eicq-v8-snac-cli-reqofflinemsgs): New.
+ (eicq-v8-snac-cli-ready): New.
+ (eicq-v8-snac-cli-families): New.
+ (eicq-v8-snac-cli-ratesrequest): New.
+ (eicq-v8-snac-cli-reqinfo): New.
+ (eicq-v8-snac-cli-reqlocation): New.
+ (eicq-v8-snac-cli-reqbuddy): New.
+ (eicq-v8-snac-cli-reqicbm): New.
+ (eicq-v8-snac-cli-reqbos): New.
+ (eicq-v8-proc-process-incoming): New.
+ (eicq-number->string): Removed.
+ (eicq-v8-number->string): New.
+ (eicq-create-flap): Removed.
+ (eicq-v8-create-flap): New.
+ (eicq-create-message): Removed.
+ (eicq-v8-number->string-swap): New.
+ (eicq-create-snac): Removed.
+ (eicq-v8-create-snac): New.
+ (eicq-v8-create-message): New.
+ (eicq-tlv-types): Removed.
+ (eicq-v8-tlv-types): New.
+ (eicq-tlv-type-value): Removed.
+ (eicq-v8-tlv-type-value): New.
+ (eicq-create-tlv): Removed.
+ (eicq-v8-create-tlv): New.
+ (eicq-parse-message): Removed.
+ (eicq-v8-string->number-le): New.
+ (eicq-v8-string->number): New.
+ (eicq-v8-grab-bytes): New.
+ (eicq-v8-grab-bytes-1): New.
+ (eicq-v8-length-1): New.
+ (eicq-v8-length-2): New.
+ (eicq-v8-length-3): New.
+ (eicq-v8-length-4): New.
+ (eicq-v8-parse-message): New.
+ (eicq-next-flap): Removed.
+ (eicq-v8-next-flap): New.
+ (eicq-next-snac): Removed.
+ (eicq-v8-next-snac): New.
+ (eicq-next-tlv): Removed.
+ (eicq-v8-next-tlv): New.
+ (eicq-v8-tlv-fetch): New.
+ (eicq-v8-tlv-get): New.
+ (eicq-login): Removed.
+ (eicq-v8-login): New.
+
+ * eicq.el (eicq-ctx): New.
+ (eicq-do-instant-message):
+ (eicq-do-offline-message):
+ (eicq-do-message-helper):
+ (eicq-bin-alias):
+ (eicq-valid-uin-p):
+ (eicq-uin): New.
+ (eicq-server): New.
+ (eicq-port): New.
+ (eicq-do-connected): New.
+ (eicq-login): Modified to use eicq-v8 to login into
+ sever. Also some custom variables introduced and some message
+ oriented functions modified.
+
+
+
+ modified files:
+ eicq-v8.el eicq.el
+
+
+2004-11-10 04:24:56 GMT Steve Youngs <steve@eicq.org> patch-1
+
+ Summary:
+ URL and email address updates for eicq.org domain
+ Revision:
+ eicq--main--0.6--patch-1
+
+
+ modified files:
+ README eicq-buddy.el eicq-comm.el eicq-convert.el eicq-log.el
+ eicq-menu.el eicq-meta.el eicq-report.el eicq-setup.el
+ eicq-status.el eicq-toolbar.el eicq-v8.el eicq-v8proto.el
+ eicq-wharf.el eicq-world.el eicq.el eicq.texi
+
+
+2004-11-10 04:22:28 GMT Steve Youngs <steve@eicq.org> base-0
+
+ Summary:
+ initial import
+ Revision:
+ eicq--main--0.6--base-0
+
+
+ (automatically generated log message)
+
+ new files:
+ ChangeLog.SFCVS INSTALL Makefile NEWS README TODO
+ eicq-buddy.el eicq-comm.el eicq-convert.el eicq-log.el
+ eicq-menu.el eicq-meta.el eicq-report.el eicq-setup.el
+ eicq-status.el eicq-toolbar.el eicq-v8.el eicq-v8proto.el
+ eicq-wharf.el eicq-world.el eicq.el eicq.texi
+
+
--- /dev/null
+# do not edit -- automatically generated by arch changelog
+# non-id: automatic-ChangeLog--steve@eicq.org--2005/eicq--main--0.7
+#
+
+2005-06-13 14:53:19 GMT Steve Youngs <steve@eicq.org> version-0
+
+ Summary:
+ Eicq 0.7 is released!
+ Revision:
+ eicq--main--0.7--version-0
+
+ Just your normal release-day doc updates.
+
+ * INSTALL: Update to include references to SXEmacs.
+
+ * Makefile (superupgrade): Remove this target, I don't use it anymore.
+ Also, update copyright notice.
+
+ * NEWS: Update.
+
+ * README: Update the "feature" section. Add some words about eicq-track
+ and eicq-history.
+
+ * TODO: Put a note in it saying that it is hideously out of date.
+ Deleted a couple of items that have either been implemented or don't
+ make sense anymore.
+
+ * eicq-track.el: Add my name to copyright notice.
+
+ * *.el: Update copyright notice.
+
+ modified files:
+ INSTALL Makefile NEWS README TODO eicq-buddy.el
+ eicq-convert.el eicq-history.el eicq-menu.el eicq-meta.el
+ eicq-report.el eicq-setup.el eicq-status.el eicq-toolbar.el
+ eicq-track.el eicq-v8.el eicq-wharf.el eicq-world.el eicq.el
+
+
+2005-06-12 12:02:47 GMT Steve Youngs <steve@eicq.org> patch-60
+
+ Summary:
+ Merged from lg@xwem.org--2005 (patch 28) -- auto-reconnect/timeout
+ Revision:
+ eicq--main--0.7--patch-60
+
+ Patches applied:
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-28
+ fixes, fetching flaps changed
+
+ My additions/tweaks to this changeset:
+
+ * eicq.el (eicq-do-disconnect): Only attempt reconnect if the user has
+ set `eicq-user-password' and `eicq-delete-offline-messages-flag' is
+ _NOT_ set to "ask". This is so unattended reconnects won't wait for
+ user input.
+
+
+ modified files:
+ eicq-v8.el eicq.el
+
+ new patches:
+ lg@xwem.org--2005/eicq--lg--0.7--patch-28
+
+
+2005-06-10 10:19:27 GMT Steve Youngs <steve@eicq.org> patch-59
+
+ Summary:
+ Fix Eicq buffer display on a TTY
+ Revision:
+ eicq--main--0.7--patch-59
+
+ * eicq.el (eicq-show-window): Don't try to create frames if we're on a
+ TTY.
+
+
+ modified files:
+ eicq.el
+
+
+2005-06-01 01:41:21 GMT Steve Youngs <steve@eicq.org> patch-58
+
+ Summary:
+ Searching for ICQ users
+ Revision:
+ eicq--main--0.7--patch-58
+
+ This changeset implements searching. With this you can now search for
+ ICQ users by: First Name, Last Name, Nick Name, Email Address. Searching
+ by UIN is supported too, but that was implemented ages ago.
+
+ There are 3 user search functions:
+
+ `eicq-search-by-uin' -- search by UIN
+ `eicq-search-by-email' -- search by email address
+ `eicq-search' -- search by any of: first name, last name, nick
+ name, email address
+
+ * eicq-v8.el (eicq-v8-snac-srv-fromicqsrv): Handle type 2010/subtype 420
+ which is all search matches except the final match. The final match is
+ subtype 430.
+ (eicq-v8-snac-cli-searchbyemail): Handle SNAC 15,2/2000/1395 searching
+ by email address.
+ (eicq-v8-snac-cli-searchbypersinf): Handle SNAC 15,2/2000/1375
+ searching by first name, last name, nick name, email address.
+ (eicq-v8-pack-llnts): New packer for data type LLNTS.
+
+ * eicq.el (eicq-do-search-found): Modify to handle search results from
+ subtype 420, ie, all matches except the final match.
+ (eicq-do-search-found-last): New. Handle search result from subtype
+ 430, ie, just the final match.
+ (eicq-login): Add new incoming handler "search-found-last" for subtype
+ 430.
+ (eicq-search): Update to new v8 protocol search.
+ (eicq-search-by-email): New. Search for users by email address.
+
+ * eicq-toolbar.el (eicq-toolbar-search): Update to use new search function.
+
+ * eicq-menu.el (eicq-main-map): Bind `F' to `eicq-search'.
+
+
+ modified files:
+ eicq-menu.el eicq-toolbar.el eicq-v8.el eicq.el
+
+
+2005-05-28 02:21:32 GMT Steve Youngs <steve@eicq.org> patch-57
+
+ Summary:
+ Another attempt at fixing eicq-history-directory being void
+ Revision:
+ eicq--main--0.7--patch-57
+
+ Third time lucky? Hopefully now eicq-history-directory won't be void for
+ people not using eicq-history.
+
+ * eicq.el (eicq-history): Moved from eicq-history.el to here.
+ (eicq-history-enabled-flag): Ditto.
+ (eicq-history-directory): Ditto.
+ (eicq-history-mode-hook): Ditto.
+
+ * eicq-history.el: Moved the defcustoms to eicq.el because of the crazy
+ interdepencies of the Eicq libs.
+
+ * eicq-report.el (eicq-report-debug): Remove eicq-history.el, there are
+ no user configurable things in there anymore.
+
+
+ modified files:
+ eicq-history.el eicq-report.el eicq.el
+
+
+2005-05-27 08:53:01 GMT Steve Youngs <steve@eicq.org> patch-56
+
+ Summary:
+ Whee little doc fix
+ Revision:
+ eicq--main--0.7--patch-56
+
+ * eicq-history.el: Teeny tiny doc fix in commentary section
+
+
+ modified files:
+ eicq-history.el
+
+
+2005-05-27 08:50:51 GMT Steve Youngs <steve@eicq.org> patch-55
+
+ Summary:
+ Fix previous fix for eicq-history
+ Revision:
+ eicq--main--0.7--patch-55
+
+ * eicq-log.el (eicq-history-directory): Revert previous change.
+
+ * eicq-buddy.el (require): Drag in eicq-history.
+
+
+ modified files:
+ eicq-buddy.el eicq-log.el
+
+
+2005-05-26 22:12:29 GMT Steve Youngs <steve@eicq.org> patch-54
+
+ Summary:
+ Fix eicq-history -- users not using it don't have to require it
+ Revision:
+ eicq--main--0.7--patch-54
+
+ * eicq-log.el (eicq-history-directory): Defvar it to nil so people _not_
+ wanting to use eicq-history don't have to require it in their set up.
+
+
+ modified files:
+ eicq-log.el
+
+
+2005-05-26 10:12:10 GMT Steve Youngs <steve@eicq.org> patch-53
+
+ Summary:
+ Fix prob with extra-buffers var containing killed buffers
+ Revision:
+ eicq--main--0.7--patch-53
+
+ * eicq.el (eicq-exit): Set `eicq-extra-buffers-to-kill' to nil after the
+ extra buffers have been killed.
+
+
+ modified files:
+ eicq.el
+
+
+2005-05-12 05:40:56 GMT Steve Youngs <steve@eicq.org> patch-52
+
+ Summary:
+ Handle "invisible" correctly.
+ Revision:
+ eicq--main--0.7--patch-52
+
+ Up until now, Eicq has not handled the "invisible" status anywhere near
+ correctly. In reality, "invisible" isn't really a status in it's own
+ right. It's a "flag" to tack onto other statuses, much like the
+ "web-aware" status is.
+
+ With that in mind, Eicq now does "invisible" in the same manner as it
+ does "web-aware". If you want to be "invisible" at login time, set
+ `eicq-user-meta-invisible' to non-nil. If you want to change your
+ visibility during your ICQ session, rat button2 on "[Invisible on/off]"
+ in the status buffer. Alternatively, `b' in the log or status buffers.
+
+ === New User Commands ===
+ eicq-toggle-invisibility
+
+ === New User Variables ===
+ eicq-user-meta-invisible -- boolean
+ eicq-user-meta-invisibility-indicator -- string
+
+ === User Variables Changed Defaults ===
+ eicq-user-initial-status -- now defaults to "online"
+
+ * eicq.el (eicq-login): Possibly set invisible with the initial status.
+
+ * eicq-log.el (eicq-log-update-modeline): New. Updates the invisibility
+ indicator in the modeline.
+ (eicq-log-mode): Use it.
+
+ * eicq-meta.el (eicq-meta): Give the group a prefix "eicq-user-meta-".
+ (eicq-user-meta-invisible): New. Set to non-nil to be "invisible" at
+ login.
+ (eicq-user-meta-invisibility-indicator): New. The value of this, a
+ string, displays in the modeline when you are "invisible".
+
+ * eicq-status.el (eicq-valid-statuses): Remove "invisible", it isn't
+ really a status in the truest sense of the word.
+ (eicq-user-initial-status): Default to "online". If you want to be
+ "invisible" at login, set `eicq-user-meta-invisible' to non-nil instead.
+ (eicq-buddy-update-status): Work^Wkludge around `eicq-user-status'
+ being set to "invisible"... it should never happen.
+ (eicq-turn-on-invisibility): New. Add invisible to status.
+ (eicq-turn-off-invisibility): New. Remove invisible from status. This
+ is the opposite of `eicq-turn-on-invisibility'.
+ (eicq-toggle-invisibility): Toggle between visible and invisible.
+ (eicq-change-status): Possibly set invisible.
+ (eicq-status-show-buffer): Use `eicq-toggle-invisibility' for the
+ "Invisible" widget in the status buffer. Also, change the text in the
+ "Invisible" widget to indicate that it is now a toggle.
+
+ * eicq-menu.el (eicq-main-map): Bind `b' to `eicq-toggle-invisibility' in
+ the log and status buffers.
+
+
+ modified files:
+ eicq-log.el eicq-menu.el eicq-meta.el eicq-status.el eicq.el
+
+
+2005-05-04 08:20:40 GMT Steve Youngs <steve@eicq.org> patch-51
+
+ Summary:
+ Extract and display `REASON' from SRV_AUTHREQ properly
+ Revision:
+ eicq--main--0.7--patch-51
+
+ * eicq-v8.el (eicq-v8-fetch-bstr): New. Fetch data type "bstr", as seen
+ in SRV_AUTHREQ.
+ (eicq-v8-snac-srv-authreq): Use it, instead of `eicq-v8-fetch-string'.
+
+ * eicq.el (eicq-do-message-helper): Don't filter auth-request messages
+ through `substring', the fetch function is DTRT now.
+
+
+ modified files:
+ eicq-v8.el eicq.el
+
+
+2005-05-03 08:46:12 GMT Steve Youngs <steve@eicq.org> patch-50
+
+ Summary:
+ Fix authorisation request reason messages
+ Revision:
+ eicq--main--0.7--patch-50
+
+ * eicq.el (eicq-do-message-helper): Parse authorisation request messages
+ through `substring' to filter out some noise.
+
+
+ modified files:
+ eicq.el
+
+
+2005-05-02 19:07:10 GMT Steve Youngs <steve@eicq.org> patch-49
+
+ Summary:
+ Add SRV_AUTHREQ handler, fix SRV_ADDEDYOU handler
+ Revision:
+ eicq--main--0.7--patch-49
+
+ * eicq.el (eicq-login): Install incoming handlers for SRV_ADDEDYOU and
+ SRV_AUTHREQ.
+ (eicq-do-added-you): Handler function for SRV_ADDEDYOU.
+ (eicq-do-auth-request): Handler function for SRV_AUTHREQ
+ (eicq-do-message-helper): Log SRV_ADDEDYOU messages as system
+ messages.
+ (eicq-sound-alist): Add a "system" sound.
+
+ * eicq-v8.el (eicq-v8-snac-srv-addedyou): Call
+ `eicq-v8-ctx-run-incoming-handler' with the appropriate keyword pairs.
+
+ * eicq-v8.el (eicq-v8-snac-srv-authreq): New. For SRV_AUTHREQ.
+
+
+ modified files:
+ eicq-v8.el eicq.el
+
+
+2005-05-01 16:07:05 GMT Steve Youngs <steve@eicq.org> patch-48
+
+ Summary:
+ The case of the disappearing smiley.
+ Revision:
+ eicq--main--0.7--patch-48
+
+ * eicq-log.el (eicq-log): Fill the message _before_ adding smilies.
+ Without this, smilies that are at eol disappear.
+
+
+ modified files:
+ eicq-log.el
+
+
+2005-05-01 09:26:57 GMT Steve Youngs <steve@eicq.org> patch-47
+
+ Summary:
+ Small regex fix in eicq-history
+ Revision:
+ eicq--main--0.7--patch-47
+
+ This fixes a problem in the history buffers when the day portion of the
+ date is a single digit starting in column 2.
+
+ * eicq-history.el (eicq-history-outline-regexp): Fix regexp to handle the
+ single digit dates of the month.
+ (eicq-history-event-regexp): Ditto.
+
+
+ modified files:
+ eicq-history.el
+
+
+2005-04-30 13:12:52 GMT Steve Youngs <steve@eicq.org> patch-46
+
+ Summary:
+ Add hyperlinks to the log buffer.
+ Revision:
+ eicq--main--0.7--patch-46
+
+ Dust off your rat, because with this change, the Eicq log buffer has
+ plenty of pointy-clicky things in it. URLs, email addresses, and even
+ Unix manual page topics are all "hot". With your rat, button2, or with
+ your keyboard, RET, on one of these links will have you browsing,
+ composing, or reading lickedy split.
+
+ * eicq-emphasis.el (eicq-emphasis-url-regexp): New. A regexp to match
+ URLs.
+ (eicq-emphasis-email-regexp): New. A regexp to match email addresses.
+ (eicq-emphasis-man-regexp): New. A regexp to match Unix manual page
+ topics.
+ (eicq-emphasis-visit-hyperlink-at-point): New. Uses `browse-url' or
+ `compose-mail' or `manual-entry' to follow links to URLs, email
+ addresses or man pages. The links themselves are extents in the log
+ buffer.
+ (eicq-emphasis-visit-hyperlink-at-mouse): New. As above, but via a
+ rat.
+ (eicq-emphasis-hyperlink-message): New. "hyperlink-er-ise" messages in
+ the log buffer.
+
+ * eicq-log.el (eicq-log): Call `eicq-emphasis-hyperlink-message' on
+ messages in the log buffer as they come in.
+
+ * eicq-log.el (eicq-log-buddy-url): Use `eicq-hyperlink-map' instead of
+ `eicq-url-map'.
+
+ * eicq-menu.el (eicq-hyperlink-map): New. Replaces `eicq-url-map'.
+ (eicq-url-map): Removed.
+
+
+ modified files:
+ eicq-emphasis.el eicq-log.el eicq-menu.el
+
+
+2005-04-29 05:51:09 GMT Steve Youngs <steve@eicq.org> patch-45
+
+ Summary:
+ Gnus-style text highlighting
+ Revision:
+ eicq--main--0.7--patch-45
+
+ With this change, the log buffer gets sexy!
+
+ _text_ is underlined
+
+ *text* is bold
+
+ /text/ is italic
+
+ _*text*_ is underlined and bold
+
+ _*/text/*_ is underlined and bold and italic
+
+ */text/* is bold and italic
+
+ _/text/_ is underlined and italic
+
+ And yes, it is customisable, so you can add others if you wish. Turn on
+ this magic with:
+
+ (setq eicq-emphasis-enabled-flag t)
+
+ * eicq-log.el (eicq-log): Maybe call `eicq-emphasis-treat-message' to do
+ Gnus-style text rendering.
+
+ * Makefile (SOURCES): Add eicq-emphasis.el
+
+ * eicq-report.el (eicq-report-debug): Add eicq-emphasis.el
+
+
+ new files:
+ .arch-ids/eicq-emphasis.el.id eicq-emphasis.el
+
+ modified files:
+ Makefile eicq-log.el eicq-report.el
+
+
+2005-04-28 22:52:03 GMT Steve Youngs <steve@eicq.org> patch-44
+
+ Summary:
+ Little tweaks and improvments to `eicq-log'
+ Revision:
+ eicq--main--0.7--patch-44
+
+ * eicq-log.el (eicq-log-buddy-url): Add balloon-help and a face to URLs.
+ (eicq-log-update-history): New. Updates the history files and makes
+ `eicq-log' shorter and simpler.
+ (eicq-log-update-tracker): New. Updates the eicq-track modeline
+ indicator and makes `eicq-log' shorter and simpler.
+ (eicq-log-update-balloon): New. Updates the balloon-help extent
+ property on the contact names in the log buffer and makes `eicq-log'
+ shorter and simpler.
+ (eicq-log): Use `eicq-log-update-{history,tracker,balloon}'.
+
+
+ modified files:
+ eicq-log.el
+
+
+2005-04-28 05:20:17 GMT Steve Youngs <steve@eicq.org> patch-43
+
+ Summary:
+ Add balloon-help coolness to contact names
+ Revision:
+ eicq--main--0.7--patch-43
+
+ * eicq-log.el (eicq-log): Set up balloon-help properties for the alias
+ extents.
+
+ * eicq-buddy.el (eicq-buddy-update-face): Set up balloon-help properties
+ for the names in the buddy buffer.
+ (eicq-buddy-show-buffer): Force a `eicq-buddy-update-face' on each name
+ to update its balloon-help extent property. It it probably a bit of
+ overkill to do it this way, but it works. Improvements very welcome.
+
+ * eicq-world.el (eicq-add-new-user-to-buddy-buffer): Add balloon-help
+ properties to the extent.
+
+
+
+ modified files:
+ eicq-buddy.el eicq-log.el eicq-world.el
+
+
+2005-04-27 22:59:09 GMT Steve Youngs <steve@eicq.org> patch-42
+
+ Summary:
+ Make all calls to play-sound-file consistent througout
+ Revision:
+ eicq--main--0.7--patch-42
+
+ * eicq.el (eicq-do-online): Use `eicq-maybe-play-sound'.
+
+ * eicq-status.el (eicq-buddy-update-status): Ditto.
+
+
+ modified files:
+ eicq-status.el eicq.el
+
+
+2005-04-24 06:27:48 GMT Steve Youngs <steve@eicq.org> patch-41
+
+ Summary:
+ Add doc string to advice in `eicq-track-init'.
+ Revision:
+ eicq--main--0.7--patch-41
+
+ * eicq-track.el (eicq-track-init): Give the advice a doc string.
+
+
+ modified files:
+ eicq-track.el
+
+
+2005-04-23 01:38:22 GMT Steve Youngs <steve@eicq.org> patch-40
+
+ Summary:
+ Merged from lg@xwem.org--2005 (patch 23)
+ Revision:
+ eicq--main--0.7--patch-40
+
+ Patches applied:
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-23
+ commented buggy and unuseful code
+
+ modified files:
+ eicq-v8.el
+
+ new patches:
+ lg@xwem.org--2005/eicq--lg--0.7--patch-23
+
+
+2005-04-23 01:30:27 GMT Steve Youngs <steve@eicq.org> patch-39
+
+ Summary:
+ eicq-track clean up, add "Riece-style" modeline indicator
+ Revision:
+ eicq--main--0.7--patch-39
+
+ This patch cleans up the eicq-track code a bit. Plus it adds a Riece
+ style modeline indicator for eicq-track. See
+ `eicq-track-indicator-type'.
+
+ The default tracking indicator style is like ERC...
+
+ [name,name2,name3...]
+
+ The Riece style is...
+
+ [E]
+
+ You can also filter out the debug, error, and system log messages so they
+ don't update the indicator. See `eicq-track-events-type'.
+
+ * eicq-track.el: Don't require eicq-log, instead just defvar
+ eicq-log-buffer at compile-time.
+ (eicq-track-visibility): Removed.
+ (eicq-track-events-type): Update doc string. Add new type, "msg" which
+ is for incoming user messages only. The "incoming" type also tracks
+ system and debug log entries too.
+ (eicq-track-shorten-to): Set custom type to integer.
+ (eicq-log-buffer-visible-p): Removed.
+ (eicq-track-clear-modeline): Use `redraw-modeline' instead of
+ `force-mode-line-update'.
+ (eicq-track-init): setq eicq-track-initialized instead of setf.
+ (eicq-track-indicator-type): New. Choose either ERC style modeline
+ indicator or Riece style.
+ (eicq-short-nick): Rename to `eicq-track-truncate-nick'.
+ (eicq-track-truncate-nick): New.
+ (eicq-track-add-nick): Rewrite to cater for both ERC style and Riece
+ style modeline indicators. Also, keep lines under 80 columns long.
+
+ * eicq.el: Don't require eicq-track here. Do it in eicq-log.el
+ instead.
+
+ * eicq-log.el: Require eicq-track.
+
+ * eicq-log.el (eicq-log): Update to allow for 'msg' type from
+ `eicq-track-events-type'.
+
+ * eicq-report.el (eicq-report-debug): Add eicq-track.el.
+
+
+ modified files:
+ eicq-log.el eicq-report.el eicq-track.el eicq.el
+
+
+2005-04-22 20:40:17 GMT Steve Youngs <steve@eicq.org> patch-38
+
+ Summary:
+ Merged from karma@sxemacs.org--2005 (patch 4) -- eicq-track
+ Revision:
+ eicq--main--0.7--patch-38
+
+ Patches applied:
+
+ * karma@sxemacs.org--2005/eicq--karma--0.7--patch-4
+ introduces `eicq-track'feature
+
+ new files:
+ .arch-ids/eicq-track.el.id eicq-track.el
+
+ modified files:
+ Makefile eicq-log.el eicq.el
+
+ new patches:
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-4
+
+
+2005-04-22 08:16:48 GMT Steve Youngs <steve@eicq.org> patch-37
+
+ Summary:
+ History improvements, eicq-setup tweaks, minor build fixes
+ Revision:
+ eicq--main--0.7--patch-37
+
+ This patch makes a few improvements to eicq-history:
+
+ - uniform `eicq-history-' naming throughout eicq-history.el
+ - history files are only saved on logout
+ - added a user command to explicitly save histories bound to `H' in
+ buddy/log buffers and `s' in history buffers.
+ - entries in history files are filled
+ - minor regexp fix to catch strange nick names in the history files.
+ - `eicq-history-here-other-window' restores the original window config
+ on exit from eicq-history-mode.
+ - the default directory for history files is now ~/.eicq/history/
+
+ There's also a couple of minor build related changes.
+
+ * Makefile (SOURCES): List the files explicitly instead of using
+ wildcards so we can control what gets compiled and in which order.
+ (EXTRA_SRC): Add eicq-version.el because it isn't getting included in
+ SOURCES anymore.
+
+ * eicq-history.el (eicq-history): New custom group.
+
+ * eicq-history.el (eicq-history-enabled-flag): New custom variable. This
+ used to be `eicq-log-per-user'.
+
+ * eicq-history.el (eicq-history-directory): New custom variable. This
+ used to be `eicq-log-per-user-directory'.
+
+ * eicq-history.el (eicq-history-mode-hook): Change custom group to
+ eicq-history.
+
+ * eicq-history.el (eicq-history-old-window-config): New. Holds the old
+ window config so when quitting the history buffer things are reset to
+ the state they were before.
+
+ * eicq-history.el (eicq-history): Add a little error checking. Stop it
+ from loading a dired buffer if the user just hits RET at the prompt for
+ a user name.
+
+ * eicq-history.el (eicq-history-here-other-window): Save the window
+ config before doing anyting else so the user comes back to the way
+ things were before he entered eicq-history-mode.
+
+ * eicq-history.el (eicq-history-event-regexp): Fix regexp to catch weird
+ nick names.
+
+ * eicq-history.el (eicq-history-mode): Don't set the fill-column. Add
+ the menu after setting the mode name, but before anything else.
+
+ * eicq-history.el (eicq-history-bury-buffer): New. This used to be
+ `eicq-history-kill-buffer'. By default it buries the buffer, with a
+ prefix arg it kills the buffer.
+
+ * eicq-history.el (eicq-history-save): New. Saves all the files in the
+ history directory that are open.
+
+ * eicq-log.el (eicq-extra-buffers-to-kill): New variable. Holds a list
+ of extra buffers to be saved/killed. Primary use is for the history
+ files. They are saved on logout and killed on exit.
+
+ * eicq-log.el (eicq-log): Use eicq-history-enabled-flag and
+ eicq-history-directory instead of the old "per-user" vars.
+ Remove an unnecessary let and its local vars.
+ Fill the entries in the history files.
+
+ * eicq-menu.el (eicq-history-menu): Add menu item for
+ `eicq-history-save'. Change "Quit" item to use
+ `eicq-history-bury-buffer'.
+
+ * eicq-menu.el (eicq-history-mode-map): Ditto.
+
+ * eicq-menu.el (eicq-main-map): Define `H' to be `eicq-history-save'.
+
+ * eicq-setup.el (eicq-setup): Require the needed libs if they aren't
+ already loaded. Check to see if each directory is nonexistent before
+ creating it. And don't use `format' with `message', it's not
+ necessary.
+
+ * eicq.el (eicq-directory): Autoload it.
+
+ * eicq.el (eicq-exit): Kill all the buffers in
+ `eicq-extra-buffers-to-kill'.
+
+ * eicq.el (eicq-logout): Save all the buffers in
+ `eicq-extra-buffers-to-kill'.
+
+
+
+ modified files:
+ Makefile eicq-history.el eicq-log.el eicq-menu.el
+ eicq-setup.el eicq.el
+
+
+2005-04-20 20:48:41 GMT Steve Youngs <steve@eicq.org> patch-36
+
+ Summary:
+ Introduce `eicq-directory' and eicq-history improvements
+ Revision:
+ eicq--main--0.7--patch-36
+
+ * eicq-history.el: Pull in eicq so we can use `eicq-directory'. And add
+ comments about using it.
+ (eicq-log-per-user-directory): Set default with `expand-file-name' and
+ `eicq-directory'. Set custom type to directory.
+ (eicq-history-mode-hook): New hook. Run after entering
+ `eicq-history-mode'.
+ (eicq-history): Simplify.
+ (eicq-history-event-regexp): Use concat and split the regexp to keep
+ the source code under 80 columns.
+ (eicq-history-mode): Move point back one line so it is on the last
+ entry in the buffer.
+ (eicq-history-kill-buffer): Don't try to swich back to the log buffer
+ because it may not exist. Also make sure the buffer being killed is in
+ `eicq-history-mode'.
+ (eicq-history-timestamp-face): Don't check if it is bound.
+ (eicq-history-event-type-face): Ditto.
+ (eicq-history-nick-face): Ditto.
+
+ * eicq-log.el (eicq-log-filename): Define with `expand-file-name' and
+ hang it off `eicq-directory'. Set custom type to file.
+ Defvar `eicq-log-per-user' and `eicq-log-per-user-directory' at compile
+ time.
+ (eicq-log): Use `expand-file-name' to get to the per-user history file.
+
+ * eicq-report.el (eicq-report-debug): Include eicq-history.el in the list
+ of files to check for changed variables.
+
+ * eicq-setup.el (eicq-setup): Create the sound and logs directories.
+
+ * eicq-world.el (eicq-world-rc-filename): Change to a defcustom.
+
+ * eicq.el (eicq-directory): New custom variable. All Eicq support files,
+ things like logs, histories, sound files, world file, go into this
+ directory or subdirectories of it.
+ (eicq-sound-directory): Hang it off `eicq-directory'.
+
+
+
+ modified files:
+ eicq-history.el eicq-log.el eicq-report.el eicq-setup.el
+ eicq-toolbar.el eicq-world.el eicq.el
+
+
+2005-04-19 21:29:00 GMT Steve Youngs <steve@eicq.org> patch-35
+
+ Summary:
+ Merged from karma@sxemacs.org--2005 (patch 1-2) -- history
+ Revision:
+ eicq--main--0.7--patch-35
+
+ This gives us the option of having mICQ-style logging... a log file for
+ each contact. You can view the history of any contact. And it makes way
+ for implementing things like `eicq-last-seen' for showing the date/time
+ you last had contact with someone.
+
+ Patches applied:
+
+ * karma@sxemacs.org--2005/eicq--karma--0.7--patch-1
+ introduces "per-user" logging and `eicq-history' feature
+
+ * karma@sxemacs.org--2005/eicq--karma--0.7--patch-2
+ small fix in `eicq-history'
+
+ new files:
+ .arch-ids/eicq-history.el.id eicq-history.el
+
+ modified files:
+ eicq-log.el eicq-menu.el eicq.el
+
+ new patches:
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-1
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-2
+
+
+2005-04-11 03:19:33 GMT Steve Youngs <steve@eicq.org> patch-34
+
+ Summary:
+ List names in buddy buffer in the same order they are in world
+ Revision:
+ eicq--main--0.7--patch-34
+
+ * eicq-world.el (eicq-world-update): Reverse the list items in
+ `eicq-world' so that the buddy buffer will display the buddies in the
+ same order that they appear in the world file.
+
+
+ modified files:
+ eicq-world.el
+
+
+2005-04-09 23:58:59 GMT Steve Youngs <steve@eicq.org> patch-33
+
+ Summary:
+ Fix auto-online where someone has requested a online notify
+ Revision:
+ eicq--main--0.7--patch-33
+
+ * eicq.el (eicq-idle-reply): Don't set eicq-auto-reply-p here.
+ (eicq-idle-reply-maybe): Set it here instead.
+
+
+ modified files:
+ eicq.el
+
+
+2005-04-07 05:59:38 GMT Steve Youngs <steve@eicq.org> patch-32
+
+ Summary:
+ Add a missing key binding for `eicq-exit' -- `X q'
+ Revision:
+ eicq--main--0.7--patch-32
+
+ * eicq-menu.el (eicq-main-map): Add binding for `eicq-exit', `X q'.
+
+
+ modified files:
+ eicq-menu.el
+
+
+2005-04-06 13:43:48 GMT Steve Youngs <steve@eicq.org> patch-31
+
+ Summary:
+ Remove =partner-version file, it wasn't such a crash hot idea
+ Revision:
+ eicq--main--0.7--patch-31
+
+
+
+2005-04-05 18:15:08 GMT Steve Youngs <steve@eicq.org> patch-30
+
+ Summary:
+ Fix bug with forwarding last message in log buffer
+ Revision:
+ eicq--main--0.7--patch-30
+
+ * eicq-log.el (eicq-log-around): If we're on the last message in the
+ buffer, the end of the message is at point-max and not at the start of
+ the next message. This fixes a bug that meant you couldn't forward the
+ last message in the log buffer.
+
+
+ modified files:
+ eicq-log.el
+
+
+2005-04-05 16:52:17 GMT Steve Youngs <steve@eicq.org> patch-29
+
+ Summary:
+ add missing patch logs
+ Revision:
+ eicq--main--0.7--patch-29
+
+ Patches applied:
+
+ * dev@xwem.org--2004-w/eicq--ckent--0.7--patch-3
+ merge from main
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-19
+ merge with main
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-20
+ helper fix for simple/normal messaging
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-21
+ merge from main
+
+
+ new patches:
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-3
+ lg@xwem.org--2005/eicq--lg--0.7--patch-19
+ lg@xwem.org--2005/eicq--lg--0.7--patch-20
+ lg@xwem.org--2005/eicq--lg--0.7--patch-21
+
+
+2005-04-02 16:56:11 GMT Steve Youngs <steve@eicq.org> patch-28
+
+ Summary:
+ Guard against runaway online notifier registering/cancelling
+ Revision:
+ eicq--main--0.7--patch-28
+
+ * eicq.el (eicq-do-message-helper): Fix regexp in string-match for online
+ notifiers so to Eicq's won't set/cancel notification requests between
+ each other because of auto-response messages.
+
+
+ modified files:
+ eicq.el
+
+
+2005-04-02 05:03:38 GMT Steve Youngs <steve@eicq.org> patch-27
+
+ Summary:
+ Improve the global keybindings -- the prefix is customisable
+ Revision:
+ eicq--main--0.7--patch-27
+
+ This patch introduces a new prefix command, `eicq-prefix'. The default
+ binding is "M-`". It is also customisable, see the new variable
+ `eicq-prefix-key'. If you wish to change its value you _MUST_ do so via
+ `customize-set-variable' and not `setq', otherwise the bindings won't be
+ set.
+
+ This change means that you will have to (require 'eicq) in your init
+ file. If you don't you won't have any global bindings, the commands will
+ be there, but no keys.
+
+ * INSTALL: Add `(require 'eicq)' to the code snippet to go in
+ ~/.sxemacs/init.el
+
+ * eicq-menu.el (eicq-prefix): New prefix command
+ Bind eicq-login, eicq-show-window, world-find with this prefix instead
+ of globally binding them all separately.
+
+ * eicq.el (eicq-install-bindings): New. Installs a key binding for
+ `eicq-prefix'.
+ (eicq-prefix-key): New customisable variable. Key for
+ `eicq-prefix'.
+
+
+ modified files:
+ INSTALL eicq-menu.el eicq.el
+
+
+2005-04-01 07:40:21 GMT Steve Youngs <steve@eicq.org> patch-26
+
+ Summary:
+ Allow other ICQ users to request online notification
+ Revision:
+ eicq--main--0.7--patch-26
+
+ With this patch if someone sends you a message with ",,notify-me" in the
+ message then Eicq will store their alias and when you go back online send
+ out a "I'm back online" message. It only happens once. If the ICQ user
+ wants to be notified the next time, they have to send another
+ "notification request message". They can also cancel a request by
+ sending you ",,cancel-notify".
+
+ * eicq.el (eicq-auto-reply-away): Set default response to mention online
+ notify requests.
+ (eicq-auto-reply-occ): Ditto.
+ (eicq-auto-reply-dnd): Ditto.
+ (eicq-auto-reply-na): Ditto.
+ (eicq-idle-reply-away): Ditto.
+ (eicq-idle-reply-na): Ditto.
+ (eicq-online-notifiers): New. Internal list of aliases who have
+ requested to be notified when we go back online after being away, na,
+ occ, or dnd.
+ (eicq-do-message-helper): Handle setting up and cancelling online
+ notifications.
+ (eicq-auto-reply): Doc string typo.
+ (eicq-idle-reply): Ditto.
+
+ * eicq-status.el (eicq-change-status): Send out the online notifications
+ if we are changing to "online". Then reset `eicq-online-notifiers' so
+ people won't get notified a 2nd time.
+
+
+ modified files:
+ eicq-status.el eicq.el
+
+
+2005-04-01 04:02:31 GMT Steve Youngs <steve@eicq.org> patch-25
+
+ Summary:
+ Fix auto-away timer not being started
+ Revision:
+ eicq--main--0.7--patch-25
+
+ * eicq.el: Make sure the auto-away idle timer is started.
+
+
+ modified files:
+ eicq.el
+
+
+2005-03-31 12:46:50 GMT Steve Youngs <steve@eicq.org> patch-24
+
+ Summary:
+ Custom and keymap fixes
+ Revision:
+ eicq--main--0.7--patch-24
+
+ * eicq-menu.el (eicq-global-map-set): Remove. Not used anymore.
+ (eicq-global-key-prefix): Ditto. These were removed so we don't pollute
+ the global keymap with commands that really have no business having
+ globally bound keys. What is needed globally has been set via a couple
+ of calls to `global-set-key'.
+ (eicq-main-menu): Add item for `eicq-change-idle-timeout'.
+
+ Remove a stack of autoload cookies from this file.
+
+ * eicq-report.el (eicq-report-debug): Don't look in eicq-menu.el, there
+ are no customisable variables there.
+
+ * eicq.el (eicq-auto-away-timeout): Fix custom type.
+ (eicq-change-idle-timeout): New. To interactively change the
+ auto-away timeout for the current session.
+ (eicq-about-fields): Move to above the "Internal variables"
+ marker so it is included in bug reports.
+ (eicq-about-more-fields): Ditto.
+
+
+ modified files:
+ eicq-menu.el eicq-report.el eicq.el
+
+
+2005-03-31 06:54:46 GMT Steve Youngs <steve@eicq.org> patch-23
+
+ Summary:
+ Fix bug with incoming messages containing `%' chars
+ Revision:
+ eicq--main--0.7--patch-23
+
+ If someone sent you a message that contained a `%', eg "we have 80% of
+ the work done", `format' would complain bitterly. This patch fixes
+ that.
+
+ * eicq-log.el (eicq-log-buddy-message): Add extra arg, FMT, for the
+ format message to pass directly to `format'.
+
+ * eicq.el (eicq-do-message-helper): Use FMT arg to
+ eicq-log-buddy-message.
+
+
+ modified files:
+ eicq-log.el eicq.el
+
+
+2005-03-30 05:53:13 GMT Steve Youngs <steve@eicq.org> patch-22
+
+ Summary:
+ Improve auto-response message sending
+ Revision:
+ eicq--main--0.7--patch-22
+
+ With this, the auto-response messages are only sent once per contact per
+ period of being not "online". It is also possible to define a list of
+ contacts that never get sent the auto-response messages. See the new
+ customisable variable: eicq-auto-response-never-send-to.
+
+
+ * eicq.el (eicq-auto-response-never-send-to): New. Holds a list of alias
+ names of people you don't want auto-response messages being sent to.
+ (eicq-auto-reply-never): New. Internal list of people not to send
+ auto-responses to.
+ (eicq-auto-reply-maybe): New. Only send auto-response if the person
+ isn't in `eicq-auto-reply-never'.
+ (eicq-idle-reply-maybe): Ditto.
+ (eicq-do-message-helper): Use `eicq-auto-reply-maybe' and
+ `eicq-idle-reply-maybe'.
+ (eicq-send-message-helper): Remove a nested `if' and change the outer
+ `if' to a `when'. Just makes things a bit cleaner. :-)
+
+ * eicq-status.el (eicq-change-status): Reset `eicq-auto-reply-never' when
+ coming back online.
+
+
+ modified files:
+ eicq-status.el eicq.el
+
+
+2005-03-29 10:01:41 GMT Steve Youngs <steve@eicq.org> patch-21
+
+ Summary:
+ Prevent echo to stdout on (S)XEmacs start up.
+ Revision:
+ eicq--main--0.7--patch-21
+
+ * eicq.el (eicq-auto-away-timeout): Remove autoload cookie.
+
+ * eicq-menu.el (eicq-global-key-prefix): Ditto.
+
+ This stops things from echo'ing to stdout on (S)XEmacs start up. It is
+ not really a problem, it just stops paranoid people from complaining.
+
+
+ modified files:
+ eicq-menu.el eicq.el
+
+
+2005-03-29 07:11:18 GMT Steve Youngs <steve@eicq.org> patch-20
+
+ Summary:
+ Improve typed message sending
+ Revision:
+ eicq--main--0.7--patch-20
+
+ * eicq-v8.el (eicq-v8-send-typed-message): Get the user's UIN from the
+ etcx thing.
+
+
+ modified files:
+ eicq-v8.el
+
+
+2005-03-29 00:36:56 GMT Steve Youngs <steve@eicq.org> patch-19
+
+ Summary:
+ Fix bug in message sending
+ Revision:
+ eicq--main--0.7--patch-19
+
+ * eicq-v8.el (eicq-v8-send-typed-message): A "typed" message must contain
+ the _sender's_ UIN in the packet.
+
+ * eicq.el (eicq-send-message-helper): For "normal" messages use
+ `eicq-v8-send-simple-message', and for "typed" messages use
+ `eicq-v8-send-typed-message'.
+
+
+ modified files:
+ eicq-v8.el eicq.el
+
+
+2005-03-28 07:34:01 GMT Steve Youngs <steve@eicq.org> patch-18
+
+ Summary:
+ Remove unnecessary advice on `display-buffer'
+ Revision:
+ eicq--main--0.7--patch-18
+
+ * eicq-buddy.el: Don't advise `display-buffer'.
+
+
+
+
+ modified files:
+ eicq-buddy.el
+
+
+2005-03-26 16:05:46 GMT Steve Youngs <steve@sxemacs.org> patch-17
+
+ Summary:
+ Merged from lg@xwem.org--2005 (patch 18) -- URL msg sending
+ Revision:
+ eicq--main--0.7--patch-17
+
+ With this patch it is possible to send URL "type 4" messages. Command
+ `u' and `U'.
+
+ Patches applied:
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-18
+ Functionality to send typed messages added.
+
+ modified files:
+ eicq-log.el eicq-v8.el eicq.el
+
+ new patches:
+ lg@xwem.org--2005/eicq--lg--0.7--patch-18
+
+
+2005-03-25 03:54:25 GMT Steve Youngs <steve@eicq.org> patch-16
+
+ Summary:
+ Merged from lg@xwem.org--2005 (patch 14, 16) status fixes
+ Revision:
+ eicq--main--0.7--patch-16
+
+
+ Patches applied:
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-14
+ fixes, searching by uin, etc
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-16
+ web-awareness, initial state fixes
+
+ My additions/tweaks:
+
+ * eicq-status.el (eicq-webaware-p): Removed. It already exists as
+ `eicq-user-meta-web-aware'.
+ (eicq-status-v8): Update doc string.
+ (eicq-change-status): Use `eicq-user-meta-web-aware'
+ instead of `eicq-webaware-p'.
+
+ * eicq.el (eicq-login): Ditto.
+ (eicq-status-v8): Autoload it.
+
+ modified files:
+ eicq-status.el eicq-v8.el eicq-world.el eicq.el
+
+ new patches:
+ lg@xwem.org--2005/eicq--lg--0.7--patch-14
+ lg@xwem.org--2005/eicq--lg--0.7--patch-16
+
+
+2005-03-22 01:45:16 GMT Steve Youngs <steve@eicq.org> patch-15
+
+ Summary:
+ itimer fixes
+ Revision:
+ eicq--main--0.7--patch-15
+
+ * eicq.el (eicq-keep-alive-stop): You can't call `delete-itimer' on just
+ an itimer name, you have to do it via `get-itimer'.
+ (eicq-auto-away-timeout-set): Ditto.
+
+
+ modified files:
+ eicq.el
+
+
+2005-03-20 06:59:21 GMT Steve Youngs <steve@eicq.org> patch-14
+
+ Summary:
+ Merged from lg@xwem.org--2005 (patch 12-13)
+ Revision:
+ eicq--main--0.7--patch-14
+
+ Patches applied:
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-12
+ More support for advanced messages
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-13
+ Making eicq-about-fields and eicq-about-more-fields customizable
+
+ modified files:
+ eicq-v8.el eicq.el
+
+ new patches:
+ lg@xwem.org--2005/eicq--lg--0.7--patch-12
+ lg@xwem.org--2005/eicq--lg--0.7--patch-13
+
+
+2005-03-19 06:37:58 GMT Steve Youngs <steve@eicq.org> patch-13
+
+ Summary:
+ Toolbar fix, compiler warning fixes, Improve info queries.
+ Revision:
+ eicq--main--0.7--patch-13
+
+ * eicq-toolbar.el (eicq-toolbar-query-info-here): Call
+ `eicq-query-info-alias-around' instead of
+ `eicq-query-info-alias-here'.
+
+ * eicq-log.el (eicq-log-show-buffer): Change the initial content of the
+ log buffer... plug `eicq-donation'
+
+ * eicq-v8.el (eicq-v8-snac-srv-replyinfo): setq count to itself to avoid
+ a compiler warning. Ugly hack, fix properly later.
+ (eicq-v8-snac-srv-recv-msg): Add a FIXME comment. This
+ defun is spewing a "variable bound but not referenced" warning. The
+ variable in question is `mrec'. I can't see why it is causing the
+ warning because it it bound AND referenced. I think the byte-compiler
+ is on drugs.
+
+ * eicq.el (eicq-do-alist): Comment out the `eicq-do-info-*' they don't
+ appear to be used anymore.
+ (eicq-do-info-not-available): Comment out... not used.
+ (eicq-do-info-ext-not-available): Ditto.
+ (eicq-do-search-found): Ditto.
+ (eicq-do-about-about): Set format width to 15.
+ (eicq-do-about-more): Set format width to 15 and update to use
+ `eicq-about-more-fields' being a simple alist instead of a complicated
+ broken customisable variable.
+ (eicq-do-about-general): Set format width to 15 and update to use
+ `eicq-about-fields' being a simple alist instead of a complicated
+ broken customisable variable.
+ (eicq-format-field): Set format width to 15 and update to use
+ `eicq-about-*-fields' being simple alists instead of a complicated
+ broken customisable variables.
+ (eicq-about-more-fields): Change to a simple alist instead of a
+ complicated and badly broken customisable variable.
+ (eicq-about-fields): Ditto.
+
+ The major noticable change here is that the info query fields are no
+ longer customisable. The defcustoms were totally screwed. They are now
+ simple defconst alists. I'll make them customisable if anyone bitches
+ about it, but I really can't see that happening.
+
+ modified files:
+ eicq-log.el eicq-toolbar.el eicq-v8.el eicq.el
+
+
+2005-03-19 00:42:16 GMT Steve Youngs <steve@eicq.org> patch-12
+
+ Summary:
+ Merged from lg@xwem.org--2005 (patch 9)
+ Revision:
+ eicq--main--0.7--patch-12
+
+ With this patch, the info query commands `i' & `I' now work.
+
+ Patches applied:
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-9
+ about info fetching done, some fixes
+
+ modified files:
+ eicq-v8.el eicq.el
+
+ new patches:
+ lg@xwem.org--2005/eicq--lg--0.7--patch-9
+
+
+2005-03-16 23:14:14 GMT Steve Youngs <steve@eicq.org> patch-11
+
+ Summary:
+ Merged from lg@xwem.org--2005 (patch 8)
+ Revision:
+ eicq--main--0.7--patch-11
+
+
+ Fixes the "Invalid len" error on status change. And partially implements
+ info queries. The info query code is far from finished, it doesn't
+ actually do any querying yet. :-P
+
+
+ Patches applied:
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-8
+ Fixes, addons
+
+ modified files:
+ eicq-v8.el eicq.el
+
+ new patches:
+ lg@xwem.org--2005/eicq--lg--0.7--patch-8
+
+
+2005-03-06 06:21:18 GMT Steve Youngs <steve@eicq.org> patch-10
+
+ Summary:
+ Code clean up, fix bug in exit stopping Eicq frame deletion.
+ Revision:
+ eicq--main--0.7--patch-10
+
+ * eicq.el (eicq-icq-client-id-string): Moved to eicq-v8.el where it is
+ called `eicq-v8-client-id-string'.
+ (eicq-disconnect): Only logout if we're connected. And don't try to
+ kill the non-existent eicq-network-buffer. This was stopping the Eicq
+ frame from being deleted if you start in a new frame.
+ (eicq-connected-p): New.
+ (eicq-disconnect): Rename it to `eicq-exit'.
+
+ * eicq-v8.el (eicq-v8-client-id-string): New.
+ (eicq-v8-login): Use it.
+
+ * eicq-toolbar.el (eicq-exit): Autoload this instead of `eicq-disconnect'.
+ (eicq-disconnect-icon): Rename to `eicq-exit-icon'.
+ (eicq-toolbar-disconnect): Rename to `eicq-toolbar-disconnect'.
+ (eicq-log-toolbar): disconnect -> exit. Move help icon
+ to right side of frame.
+
+ * eicq-menu.el (eicq-main-menu): Rename "disconnect" to "exit".
+
+ * eicq-log.el (eicq-log-show-buffer): Change the header in log files to
+ say (S)XEmacs.
+
+
+ modified files:
+ eicq-log.el eicq-menu.el eicq-toolbar.el eicq-v8.el eicq.el
+
+
+2005-03-06 04:03:48 GMT Steve Youngs <steve@eicq.org> patch-9
+
+ Summary:
+ Fix statuses and auto/idle responses
+ Revision:
+ eicq--main--0.7--patch-9
+
+ This fixes a bug that was causing Eicq to send the wrong auto-response
+ message when you had "idle'd" away/na.
+
+ * eicq-status.el (eicq-statuses): Lets just call "na99" "na" and
+ "occ-mac" "occ".
+ (eicq-status-idle-reply): Make it return idle responses instead of auto
+ responses like it was.
+
+
+ modified files:
+ eicq-status.el eicq.el
+
+
+2005-03-06 02:57:19 GMT Steve Youngs <steve@eicq.org> patch-8
+
+ Summary:
+ General tidy up.
+ Revision:
+ eicq--main--0.7--patch-8
+
+ General all-purpose tidy up. Most of the stuff here is internal and
+ should go pretty much unnoticed.
+
+ One user-visible change is that `h', `eicq-hide-window', now hides _all_
+ Eicq windows. So when the boss walks in, hit `h' and all traces of Eicq
+ will vanish from view. :-) `M-` w' brings it all back.
+
+ The file eicq-comm.el has been removed. I'm not sure if make upgrade
+ will delete it from the install dir, so you might have to rm it manually
+ from the install dir.
+
+ * eicq.el (eicq-logout): Remove KILL arg, it isn't used anymore.
+ (eicq-disconnect): Call `eicq-logout' without any args.
+ (eicq-do-kicked-out): Ditto. Hmm, does this function get used anymore?
+ (eicq-hide-window): Don't try hiding eicq-network-buffer, it doesn't exist.
+ Make it hide the buffers properly. It used to leave the log or buddy,
+ whichever was current, now it hides em all!
+ (eicq-dropped-packet-counter): Moved here from the old eicq-comm.el
+ (eicq-resend-packet-counter): Ditto.
+ (eicq-recent-packet): Ditto.
+ (eicq-trimmed-packet-counter): Ditto.
+ (eicq-error-packets): Ditto.
+ (eicq-send-internal): Removed. Not used anymore.
+ (eicq-user-password): Moved here from the old eicq-comm.el.
+ (eicq-send-queue-start): Removed.
+ (eicq-send-queue-stop): Removed.
+ (eicq-logout): Don't try to stop the send queue, it doesn't exist.
+ (eicq-disconnect): Don't call nonexistent `eicq-network-kill'.
+ (eicq-auto-reply-away): Eicq is the _(S)XEmacs_ ICQ client!
+ (eicq-auto-reply-occ): Ditto.
+ (eicq-auto-reply-dnd): Ditto.
+ (eicq-idle-reply-away): Ditto.
+ (eicq-idle-reply-na): Ditto.
+
+
+ * eicq-v8.el (eicq-debug-buffer): New.
+
+ * eicq-v8.el (eicq-v8-debug): Use it.
+
+ * eicq-menu.el (eicq-main-map): Don't define a key to switch to the
+ "network" buffer... there is none.
+
+ * eicq-menu.el (eicq-main-menu): No menu entry for switching to network
+ buffer.
+
+ * *: Remove all the "Last-Modified" headers and local variables section
+ on all files. They were the source of too many merge conflicts.
+
+
+ removed files:
+ .arch-ids/eicq-comm.el.id eicq-comm.el
+
+ modified files:
+ eicq-buddy.el eicq-convert.el eicq-log.el eicq-menu.el
+ eicq-meta.el eicq-report.el eicq-setup.el eicq-status.el
+ eicq-toolbar.el eicq-v8.el eicq-wharf.el eicq-world.el eicq.el
+ eicq.texi
+
+
+2005-03-03 06:28:43 GMT Steve Youngs <steve@eicq.org> patch-7
+
+ Summary:
+ Automatically mark incoming msg's read on reply
+ Revision:
+ eicq--main--0.7--patch-7
+
+ * eicq.el (eicq-send-message-alias-around): Mark incoming messages
+ automatically when you reply to them with `m'.
+ (eicq-send-url-alias-around): Same here with replying with `u'.
+
+
+ modified files:
+ eicq.el
+
+
+2005-03-03 02:26:34 GMT Steve Youngs <steve@eicq.org> patch-6
+
+ Summary:
+ Merged from lg@xwem.org--2005 (patch 5)
+ Revision:
+ eicq--main--0.7--patch-6
+
+ Patches applied:
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-5
+ merge from ckent, bug fixes, mark as read addon
+
+ My additions...
+
+ * eicq-toolbar.el (eicq-toolbar-disconnect): Don't call `eicq-logout'
+ here because `eicq-disconnect' calls it anyway.
+
+ * eicq.el (eicq-logout): Make sure we run `eicq-v8-close'
+
+
+ modified files:
+ eicq-log.el eicq-toolbar.el eicq-v8.el eicq.el
+
+ new patches:
+ lg@xwem.org--2005/eicq--lg--0.7--patch-5
+
+
+2005-03-02 00:56:28 GMT Steve Youngs <steve@eicq.org> patch-5
+
+ Summary:
+ log buffer fixes -- faces, fill-column, smilies.
+ Revision:
+ eicq--main--0.7--patch-5
+
+ * eicq-log.el (eicq-log-fill-column): Set to zero and make the custom
+ type integer. The fill-column in the log buffer is now computed based
+ on the width of the frame, but it can be overridden if this in
+ non-zero.
+ (eicq-log-mode): Calculate the fill-column based on the frame width.
+ If `eicq-log-fill-column' is non-zero, use that instead.
+ Also improve the modeline format for the log buffer.
+ (eicq-log): Set the extent face for buddy names in the log buffer
+ according to their status.
+ Smilify messages here instead of in `eicq-log-buddy-message' and use
+ `smiley-region' on the individual message rather than `smiley-buffer'.
+ This gives a considerable speed up when you have huge log buffers.
+ (eicq-log-buddy-message): Don't set smilies here. Do it in
+ `eicq-log'.
+
+ * eicq-status.el (eicq-face-invisible): New face.
+ (eicq-face-offline): Removed.
+
+ * eicq-status.el (eicq-statuses): Set the face for invisible to
+ `eicq-face-invisible' and the face for offline to nil.
+
+ * eicq-status.el (eicq-buddy-update-status): Set the status before
+ logging it to ensure the correct face is used in the log buffer.
+
+ * eicq-status.el (eicq-status-show-buffer): Use `eicq-log-face-invisible'
+ for the "[Invisible]" widget.
+
+
+ modified files:
+ eicq-log.el eicq-status.el
+
+
+2005-02-28 00:01:58 GMT Steve Youngs <steve@eicq.org> patch-4
+
+ Summary:
+ Merged from lg@xwem.org--2005 (patch 2)
+ Revision:
+ eicq--main--0.7--patch-4
+
+ Patches applied:
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-2
+ send/recv fixes, world-update
+
+ modified files:
+ eicq-v8.el eicq-world.el eicq.el
+
+ new patches:
+ lg@xwem.org--2005/eicq--lg--0.7--patch-2
+
+
+2005-02-27 07:35:24 GMT Steve Youngs <steve@eicq.org> patch-3
+
+ Summary:
+ Remove the need to set `eicq-uin'
+ Revision:
+ eicq--main--0.7--patch-3
+
+ * eicq.el (eicq-login): Get eicq-uin from the world file like we did in
+ the old days. This removes the requirement of setting eicq-uin.
+ (eicq-uin): Remove. It isn't needed.
+
+
+ modified files:
+ eicq.el
+
+
+2005-02-27 01:30:31 GMT Steve Youngs <steve@eicq.org> patch-2
+
+ Summary:
+ Merged from dev@xwem.org--2004-w (patch 1-2), lg@xwem.org--2005 (patch 1)
+ Revision:
+ eicq--main--0.7--patch-2
+
+ This change should mean that Eicq is once again usable! You should be
+ able to log in and send/receive at least basic messages.
+
+ You _will_ need to (setq eicq-uin 123456789) for your UIN at this stage.
+ That requirement will be removed in the very near future.
+
+ Looks like we're back in business. :-)
+
+
+ Patches applied:
+
+ * dev@xwem.org--2004-w/eicq--ckent--0.7--patch-1
+ eicq-v8 addons and fixes
+
+ * dev@xwem.org--2004-w/eicq--ckent--0.7--patch-2
+ minor fixes
+
+ * lg@xwem.org--2005/eicq--lg--0.7--patch-1
+ fixes, little restructurisation
+
+ modified files:
+ Makefile eicq-log.el eicq-status.el eicq-v8.el eicq-world.el
+ eicq.el
+
+ new patches:
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-1
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-2
+ lg@xwem.org--2005/eicq--lg--0.7--patch-1
+
+
+2004-12-31 22:51:52 GMT Steve Youngs <steve@eicq.org> patch-1
+
+ Summary:
+ Add ChangeLog from prev version, bump VER in Makefile
+ Revision:
+ eicq--main--0.7--patch-1
+
+
+ new files:
+ ChangeLog.d/.arch-ids/=id
+ ChangeLog.d/.arch-ids/ChangeLog-0.6.id
+ ChangeLog.d/ChangeLog-0.6
+
+ modified files:
+ Makefile
+
+ new directories:
+ ChangeLog.d ChangeLog.d/.arch-ids
+
+
+2004-12-31 21:39:09 GMT Steve Youngs <steve@eicq.org> base-0
+
+ Summary:
+ tag of steve@eicq.org--2004/eicq--main--0.6--patch-15
+ Revision:
+ eicq--main--0.7--base-0
+
+ (automatically generated log message)
+
+ new patches:
+ steve@eicq.org--2004/eicq--main--0.6--base-0
+ steve@eicq.org--2004/eicq--main--0.6--patch-1
+ steve@eicq.org--2004/eicq--main--0.6--patch-2
+ steve@eicq.org--2004/eicq--main--0.6--patch-3
+ steve@eicq.org--2004/eicq--main--0.6--patch-4
+ steve@eicq.org--2004/eicq--main--0.6--patch-5
+ steve@eicq.org--2004/eicq--main--0.6--patch-6
+ steve@eicq.org--2004/eicq--main--0.6--patch-7
+ steve@eicq.org--2004/eicq--main--0.6--patch-8
+ steve@eicq.org--2004/eicq--main--0.6--patch-9
+ steve@eicq.org--2004/eicq--main--0.6--patch-10
+ steve@eicq.org--2004/eicq--main--0.6--patch-11
+ steve@eicq.org--2004/eicq--main--0.6--patch-12
+ steve@eicq.org--2004/eicq--main--0.6--patch-13
+ steve@eicq.org--2004/eicq--main--0.6--patch-14
+ steve@eicq.org--2004/eicq--main--0.6--patch-15
+
+
--- /dev/null
+# do not edit -- automatically generated by arch changelog
+# non-id: automatic-ChangeLog--steve@eicq.org--2005/eicq--main--0.8
+#
+
+2005-12-26 04:40:03 GMT Steve Youngs <steve@eicq.org> versionfix-1
+
+ Summary:
+ Oops, forgot to update the NEWS file.
+ Revision:
+ eicq--main--0.8--versionfix-1
+
+ * NEWS: Update.
+
+
+ modified files:
+ NEWS
+
+
+2005-12-26 03:13:24 GMT Steve Youngs <steve@eicq.org> version-0
+
+ Summary:
+ Eicq 0.8 is released!
+ Revision:
+ eicq--main--0.8--version-0
+
+
+
+2005-11-20 13:40:16 GMT Steve Youngs <steve@eicq.org> patch-23
+
+ Summary:
+ Merged from lg (patch 3) -- BBDB build fix
+ Revision:
+ eicq--main--0.8--patch-23
+
+ This fixes a problem with trying to autoload `bbdb-records'. My addition
+ to it is...
+
+ * eicq-buddy.el: autoload `regexp-opt' at compile time.
+
+
+
+ Patches applied:
+
+ * lg@xwem.org--2005/eicq--lg--0.8--patch-3
+ eicq-buddy bbdb requirements fix
+
+ modified files:
+ eicq-buddy.el
+
+ new patches:
+ lg@xwem.org--2005/eicq--lg--0.8--patch-3
+
+
+2005-11-20 02:44:05 GMT Steve Youngs <steve@eicq.org> patch-22
+
+ Summary:
+ Merged from lg (patch 4) -- key bind fix
+ Revision:
+ eicq--main--0.8--patch-22
+
+ Unbind the old prefix key when you change it.
+
+ Patches applied:
+
+ * lg@xwem.org--2005/eicq--lg--0.8--patch-4
+ eicq-prefix-key customisation fix
+
+ modified files:
+ eicq.el
+
+ new patches:
+ lg@xwem.org--2005/eicq--lg--0.8--patch-4
+
+
+2005-11-20 01:30:13 GMT Steve Youngs <steve@eicq.org> patch-21
+
+ Summary:
+ Merged from lg (patch 1-2) -- Support Russian out of the box.
+ Revision:
+ eicq--main--0.8--patch-21
+
+ Patches applied:
+
+ * lg@xwem.org--2005/eicq--lg--0.8--patch-1
+ Encoding translation added
+
+ * lg@xwem.org--2005/eicq--lg--0.8--patch-2
+ track typo fix, encodings mess
+
+ modified files:
+ eicq-log.el eicq-track.el eicq.el
+
+ new patches:
+ lg@xwem.org--2005/eicq--lg--0.8--patch-1
+ lg@xwem.org--2005/eicq--lg--0.8--patch-2
+
+
+2005-10-20 03:20:12 GMT Steve Youngs <steve@eicq.org> patch-20
+
+ Summary:
+ Don't call `eicq-show-window' if auto-reconnecting.
+ Revision:
+ eicq--main--0.8--patch-20
+
+ I've been seeing this for a while. If you lost your connection to ICQ
+ for some reason and Eicq does an auto-reconnect, `current-buffer' was
+ being left at `eicq-log-buffer' instead of the displayed buffer.
+
+ This fairly trivial changes fixes that.
+
+ * eicq.el (eicq-is-auto-reconnecting): New. This is non-nil when Eicq is
+ in the process of performing an auto-reconnect.
+ (eicq-do-disconnect): Set `eicq-is-auto-reconnecting' to non-nil.
+ (eicq-do-login-confirm): Only call `eicq-show-window' if
+ `eicq-is-auto-reconnecting' is nil.
+
+
+ modified files:
+ eicq.el
+
+
+2005-10-15 07:06:28 GMT Steve Youngs <steve@eicq.org> patch-19
+
+ Summary:
+ Eicq activity indicator in XWEM
+ Revision:
+ eicq--main--0.8--patch-19
+
+ This change means that XWEM users can put a sexy little activity
+ indicator in the XWEM systray. See the top of eicq-xwem.el for the
+ no-brainer instructions on how to use it.
+
+ * eicq-track.el (eicq-track-activity-hook): New hook. It's called when
+ eicq-track adds to the modeline.
+ (eicq-track-clear-hook): New hook. It's called when eicq-track clears
+ the modeline.
+ (eicq-track-add-nick): Run the `eicq-track-activity-hook' hooks.
+ (eicq-track-clear-modeline): Run the `eicq-track-clear-hook' hooks.
+
+ * eicq-xwem.el: New file! Put a sexy indicator icon into the XWEM
+ systray.
+
+ * Makefile (SOURCES): Add eicq-xwem.el
+
+ * eicq-report.el: Something happened to one of the libs this needs... now
+ we need regexp-opt too.
+
+
+
+ new files:
+ .arch-ids/eicq-xwem.el.id eicq-xwem.el
+
+ modified files:
+ Makefile eicq-report.el eicq-track.el
+
+
+2005-09-20 17:04:17 GMT Steve Youngs <steve@eicq.org> patch-18
+
+ Summary:
+ Gutter updates -- "Online" button logs in if needed
+ Revision:
+ eicq--main--0.8--patch-18
+
+ * eicq-status.el (eicq-status-maybe-login): New. For use with the
+ "Online" gutter button. If you are offline, it'll log you in, if you
+ are online but set to another status like "away" it'll change your
+ status to "online".
+
+ Also don't update the gutter every time there's a status change. The
+ gutter wasn't updating properly anyway. Once the gutter bugs are sorted
+ this will probably be put back in.
+
+
+ modified files:
+ eicq-status.el
+
+
+2005-09-14 05:33:35 GMT Steve Youngs <steve@eicq.org> patch-17
+
+ Summary:
+ The Doctor is in!
+ Revision:
+ eicq--main--0.8--patch-17
+
+ This change means you can let your ICQ contact pyscho-analyze
+ themselves. To enable it, set `eicq-doctor-enabled-flag' to `t'. Then
+ when somebody sends you a message with ",,doctor" the doctor will begin
+ the therapy session.
+
+ * eicq-doctor.el: New file. Let your contacts pyscho-analyze
+ themselves.
+
+ * eicq-report.el (eicq-report-debug): Add eicq-doctor.el.
+
+ * eicq.el (eicq-do-message-helper): Handle doctor messages.
+
+ * Makefile (SOURCES): Add eicq-doctor.el.
+
+ * TODO: Remove item about adding eicq-doctor. The doctor is in!
+
+
+ new files:
+ .arch-ids/eicq-doctor.el.id eicq-doctor.el
+
+ modified files:
+ Makefile TODO eicq-report.el eicq.el
+
+
+2005-09-13 04:18:18 GMT Steve Youngs <steve@eicq.org> patch-16
+
+ Summary:
+ Add an "oops" function
+ Revision:
+ eicq--main--0.8--patch-16
+
+ How many times have you `m some message here RET' only to discover that
+ it went to the wrong person? Here is `eicq-oops'. It sends the message
+ to the right person and a "oops" message to the wrong person.
+
+ It is bound to `O' in the log buffer and you can customise the "oops"
+ message, see `eicq-oops-msg-wrong-recipient'.
+
+ * eicq.el (eicq-oops-msg-wrong-recipient): New. When you send a message
+ to the wrong person and then invoke `eicq-oops', this gets sent to the
+ original person as an explanation.
+ (eicq-oops): New. Send an "oops" message to the wrong person and send
+ the original message to the right person.
+
+ * eicq-menu.el (eicq-log-mode-map): Bind `O' to `eicq-oops'.
+ (eicq-log-menu): Add menu item for `eicq-oops'.
+
+ * TODO: Remove item about implementing an `eicq-oops' function.
+
+
+ modified files:
+ TODO eicq-menu.el eicq.el
+
+
+2005-09-10 17:17:50 GMT Steve Youngs <steve@eicq.org> patch-15
+
+ Summary:
+ Stop the status gutter appearing after `eicq-hide-windows'
+ Revision:
+ eicq--main--0.8--patch-15
+
+ This fixes a bug in the status gutter that was causing the gutter to
+ display when Eicq was supposedly hidden.
+
+ * eicq.el (eicq-window-hidden-p): New. Return non-nil if the Eicq
+ buffers are hidden.
+
+ * eicq-status.el: Only run `eicq-update-tab-in-gutter' from
+ `eicq-status-update-hook' if the Eicq buffers aren't hidden.
+
+
+ modified files:
+ eicq-status.el eicq.el
+
+
+2005-09-10 16:42:16 GMT Steve Youngs <steve@eicq.org> patch-14
+
+ Summary:
+ Better handling of switching between log and buddy buffers
+ Revision:
+ eicq--main--0.8--patch-14
+
+ * eicq.el (eicq-switch-buffer): New. For switching between the log and
+ buddy buffers.
+ (eicq-show-window): Use it.
+ (eicq-switch-to-buddy-buffer): Moved here from eicq-buddy.el, uses
+ `eicq-switch-buffer'.
+ (eicq-switch-to-log-buffer): New.
+
+ * eicq-buddy.el (eicq-switch-to-buddy-buffer): Removed. This is now in
+ eicq.el.
+
+ * eicq-menu.el (eicq-buddy-mode-map): Bind `o' to
+ `eicq-switch-to-log-buffer' instead of `other-window'.
+
+
+ modified files:
+ eicq-buddy.el eicq-menu.el eicq.el
+
+
+2005-09-10 09:10:48 GMT Steve Youngs <steve@eicq.org> patch-13
+
+ Summary:
+ Fix `eicq-switch-to-buddy-buffer' when using status gutter
+ Revision:
+ eicq--main--0.8--patch-13
+
+ * eicq-buddy.el (eicq-switch-to-buddy-buffer): Allow for the possibility
+ of there being no status buffer.
+
+
+ modified files:
+ eicq-buddy.el
+
+
+2005-09-10 04:04:22 GMT Steve Youngs <steve@eicq.org> patch-12
+
+ Summary:
+ Status gutter update
+ Revision:
+ eicq--main--0.8--patch-12
+
+ * eicq-status.el (eicq-status-tabs): Simplify a little, but it still
+ isn't doing the right thing. :-(
+
+
+ modified files:
+ eicq-status.el
+
+
+2005-09-10 03:07:14 GMT Steve Youngs <steve@eicq.org> patch-11
+
+ Summary:
+ Status gutter updates.
+ Revision:
+ eicq--main--0.8--patch-11
+
+ This change fixes the problem of gutters showing up in other frames once
+ the Eicq status gutter was set. It also adds an "Offline" tab and allows
+ the user to set the gutter to the top or bottom of the frame. Setting
+ the gutter to the right or left is currently broken.
+
+ * eicq-status.el (eicq-status-gutter-orientation): New user customisable
+ variable. For setting the location of the status gutter. Currently
+ only `top' and `bottom' work, while `right' and `left' are broken.
+ (eicq-status-tabs): Add a "Offline" tab.
+ (eicq-add-tab-to-gutter): New.
+ (eicq-update-tab-in-gutter): Use it.
+ Take out references to the global-buffers-tab stuff.
+
+
+ modified files:
+ eicq-status.el
+
+
+2005-09-09 04:21:48 GMT Steve Youngs <steve@eicq.org> patch-10
+
+ Summary:
+ Make `eicq-hide-window' hide the status gutter too.
+ Revision:
+ eicq--main--0.8--patch-10
+
+ * eicq.el (eicq-show-window): Make the gutter visible if it's being
+ used.
+ (eicq-hide-window): Hide the Eicq status gutter if it is being used.
+
+
+ modified files:
+ eicq.el
+
+
+2005-09-09 01:30:15 GMT Steve Youngs <steve@eicq.org> patch-9
+
+ Summary:
+ Display status buffer info in a gutter
+ Revision:
+ eicq--main--0.8--patch-9
+
+ This allows you to have the info that is normally displayed in the
+ status buffer displayed in the gutter area instead. Take care with this,
+ it is definitely "experimental" code and is still broken in a number of
+ ways.
+
+ To enable this, set `eicq-status-use-gutter' to `t'.
+
+ * eicq-status.el (eicq-do-status-update): Run `eicq-status-update-hook'
+ _after_ the status has been changed.
+ (eicq-status-use-gutter): New. When non-nil, display status switching
+ widgets in the gutter instead of in a buffer.
+ (eicq-status-gutter-tab): New.
+ (eicq-status-tabs): New.
+ (eicq-update-tab-in-gutter): New.
+
+ * eicq.el (eicq-show-window): Use new status gutter code.
+
+
+ modified files:
+ eicq-status.el eicq.el
+
+
+2005-09-04 02:10:32 GMT Steve Youngs <steve@eicq.org> patch-8
+
+ Summary:
+ Don't use Gnus for displaying Face colour glyphs
+ Revision:
+ eicq--main--0.8--patch-8
+
+ This takes away the need to have Gnus just to display those cute sexy
+ colour face glyphs.
+
+ * eicq-buddy.el (eicq-face-to-png): New.
+ (eicq-buddy-show-xface): Use it.
+ Also, minor tweak to logic.
+
+
+ modified files:
+ eicq-buddy.el
+
+
+2005-09-03 01:48:54 GMT Steve Youngs <steve@eicq.org> patch-7
+
+ Summary:
+ Update TODO
+ Revision:
+ eicq--main--0.8--patch-7
+
+ * TODO: Remove item about X-Face... it's done!
+
+
+ modified files:
+ TODO
+
+
+2005-09-03 01:27:06 GMT Steve Youngs <steve@eicq.org> patch-6
+
+ Summary:
+ Display colour face images or X-Face images in buddy buffer
+ Revision:
+ eicq--main--0.8--patch-6
+
+ With this change, if a contact in your buddy buffer has a `cface' field
+ in their BBDB record, that image will be displayed. If a contact has
+ both a `cface' and a X-Face, the cface will be displayed. You can
+ reverse that preference by setting `eicq-buddy-prefer-cface-to-xface' to
+ nil.
+
+ * eicq-buddy.el (eicq-buddy-show-xface): Teeny tiny doc update.
+ (eicq-buddy-prefer-cface-to-xface): New. If this is non-nil and a
+ contact has both an X-Face and a colour PNG face image, the colour one
+ will be displayed in the buddy buffer.
+ (eicq-buddy-show-xface): Possibly display colour face images.
+ Put some whitespace between the face image and the contact name.
+
+ * README: Mention setting up X-Face and colour Face image display.
+
+
+ modified files:
+ README eicq-buddy.el
+
+
+2005-09-02 06:33:51 GMT Steve Youngs <steve@eicq.org> patch-5
+
+ Summary:
+ Display X-Face images in buddy buffer
+ Revision:
+ eicq--main--0.8--patch-5
+
+ With this change you can optionally display X-Face images for the
+ contacts in the buddy buffer. The data for the image comes from the
+ `face' field of the contact's BBDB record.
+
+ To use this you have to add a new field to your BBDB records. The new
+ field is called "icqnick" and its value is the alias/buddy name that is
+ used in the buddy buffer.
+
+ As yet, there is no way to update your BBDB from within Eicq. Maybe
+ later. :-)
+
+ Once you have BBDB set up correctly, enable this new eye-candy in Eicq
+ with:
+
+ (setq eicq-buddy-show-xface t)
+
+ * eicq-buddy.el (eicq-buddy-show-xface): New. When non-nil, display
+ X-Face images in the buddy buffer.
+ (eicq-buddy-show-xface): New function for displaying X-Face images in
+ the buddy buffer.
+ (eicq-buddy-show-buffer): Use them.
+
+
+ modified files:
+ eicq-buddy.el
+
+
+2005-07-09 22:01:22 GMT Steve Youngs <steve@eicq.org> patch-4
+
+ Summary:
+ Fix bug of trying to play undefined sounds
+ Revision:
+ eicq--main--0.8--patch-4
+
+ * eicq.el (eicq-maybe-play-sound): Check to see if sound TYPE is actually
+ defined before trying to play it.
+
+
+ modified files:
+ eicq.el
+
+
+2005-06-22 13:31:54 GMT Steve Youngs <steve@eicq.org> patch-3
+
+ Summary:
+ Cleaner UI
+ Revision:
+ eicq--main--0.8--patch-3
+
+ This looks a bit nicer, so says my wife. :-)
+
+ * eicq-status.el (eicq-status-window-height): Set to 8. The status
+ buffer not having a modeline means we can make the buffer a little
+ smaller.
+ (eicq-status-show-buffer): Turn off the modeline and don't set the
+ modeline format.
+
+ * eicq-buddy.el (eicq-buddy-mode): Turn off the modeline and the
+ horizontal scrollbar.
+
+
+ modified files:
+ eicq-buddy.el eicq-status.el
+
+
+2005-06-20 03:00:40 GMT Steve Youngs <steve@eicq.org> patch-2
+
+ Summary:
+ Old v5 protocol bitrot removal
+ Revision:
+ eicq--main--0.8--patch-2
+
+ This gets rid of hopefully all of the old stagnating v5 protocol code.
+ I've also added lots of "FIXME" comments, so if you're looking for
+ something to do... :-)
+
+ * eicq.el (eicq-pretty-hex): Removed.
+ (eicq-bin-pretty-hex): Removed.
+ (eicq-redo-hex): Removed.
+ (eicq-hex-bin): Removed.
+ (eicq-byte-int): Removed.
+ (eicq-pack-contact-list): Removed.
+ (eicq-int-byte): Removed.
+ (eicq-pack-send-message): Removed.
+ (eicq-alias-bin): Removed.
+ (eicq-uin-bin): Removed.
+ (eicq-bin-uin): Removed.
+ (eicq-do-online): Commented out. See FIXME comment about why I didn't
+ just nuke it entirely.
+ (eicq-do-new-account-uin): Ditto.
+ (eicq-do-search-random-user-found): Ditto.
+ (eicq-bin-ip): Removed.
+ (eicq-pack-v5): Removed.
+ (eicq-pack-keep-alive): Removed.
+ (eicq-pack-logout): Removed.
+ (eicq-pack-delete-offline-messages): Removed.
+ (eicq-pack-invisible-list): Removed.
+ (eicq-pack-visible-list): Removed.
+ (eicq-pack-register-new-user): Commented out. See FIXME comment about
+ why I didn't just nuke it entirely.
+ (eicq-pack-search): Removed.
+ (eicq-pack-set-random-group): Commented out. See FIXME comment about
+ why I didn't just nuke it entirely.
+ (eicq-pack-search-random-user): Ditto.
+ (eicq-pack-request-authorization): Ditto.
+ (eicq-pack-query-servers): Removed.
+ (eicq-pack-query-addons): Removed.
+ (eicq-pack-new-account-permission): Removed.
+ (eicq-pack-new-account-register): Removed.
+ (eicq-pack-cmd-x1): Removed.
+ (eicq-pack-send-message-to-foreigner): Removed.
+ (eicq-do-alist): Removed.
+ (eicq-do): Removed.
+ (eicq-do-ack): Removed.
+ (eicq-do-unknown): Commented out. See FIXME comment about why I didn't
+ just nuke it entirely.
+ (eicq-do-wrong-password): Ditto.
+ (eicq-do-already-logged-in): Ditto.
+ (eicq-do-offline-message-complete): Removed.
+ (eicq-do-offline): Removed.
+ (eicq-do-system-message): Commented out. See FIXME comment.
+ (eicq-do-update-info-confirm): Ditto.
+ (eicq-do-update-info-fail): Ditto.
+ (eicq-do-update-authorization-confirm): Ditto.
+ (eicq-do-update-authorization-fail): Ditto.
+ (eicq-do-update-info-ext-confirm): Ditto.
+ (eicq-do-query-servers-reply): Removed.
+ (eicq-do-multi): Removed.
+ (eicq-bin-alias): Removed.
+ (eicq-authorize): Add FIXME comment.
+ (eicq-register-new-user): Comment out. Add FIXME comment.
+ (eicq-change-password): Ditto.
+ (eicq-search-random-user): Ditto.
+ (eicq-set-random-group): Ditto.
+ (eicq-delete-offline-messages-flag): Removed. Doesn't look like v8
+ protocol gives you the choice to delete from the server or not. Once
+ they are sent and acknowledged, that's it.
+ (eicq-do-disconnect): No need to test for whether the user wants to be
+ asked about deleting offline messages... he isn't.
+ (eicq-delete-offline-messages): Removed. v8 doesn't do this.
+ (eicq-bin-hex): Removed.
+ (eicq-session-id): Removed.
+ (eicq-int-bin): Removed.
+ (eicq-send): Removed.
+ (eicq-network-filter): Removed.
+ (eicq-network-separator): Removed.
+ (eicq-bin-int): Removed.
+
+ * eicq-meta.el (eicq-pack-meta-user-change-password): Removed.
+ (eicq-pack-meta-user-query): Removed.
+ (eicq-country-code): Removed.
+ (eicq-pack-meta-user-update-general): Commented out. FIXME comment
+ added.
+ (eicq-pack-meta-user-security): Ditto.
+ (eicq-pack-meta-user-update-work): Ditto.
+ (eicq-pack-meta-user-update-more): Ditto.
+ (eicq-pack-meta-user-update-about): Ditto.
+ (eicq-do-meta-alist): Ditto.
+ (eicq-do-meta-user): Ditto.
+ (eicq-do-meta-user-unknown): Ditto.
+ (eicq-do-meta-user-general): Removed.
+ (eicq-do-meta-user-work): Removed.
+ (eicq-do-meta-user-more): Removed.
+ (eicq-do-meta-user-about): Removed.
+ (eicq-do-meta-user-interest): Removed.
+ (eicq-do-meta-user-background): Removed.
+ (eicq-do-meta-user-picture): Removed.
+ (eicq-do-meta-user-found): Removed.
+ (eicq-do-meta-user-update-general-confirm): Removed.
+ (eicq-do-meta-user-update-work-confirm): Removed.
+ (eicq-do-meta-user-update-more-confirm): Removed.
+ (eicq-do-meta-user-update-about-confirm): Removed.
+ (eicq-do-meta-user-update-security-confirm): Removed.
+ (eicq-do-meta-user-password): Removed.
+ (eicq-update-meta-info): Commented out. FIXME comment
+ added.
+
+ * eicq-world.el (eicq-world-update): Don't setq eicq-user-bin. Not used
+ anymore.
+ (eicq-toolbar-update-info): Display a message stating this feature
+ isn't implemented yet.
+
+
+ modified files:
+ eicq-meta.el eicq-toolbar.el eicq-world.el eicq.el
+
+
+2005-06-13 15:43:49 GMT Steve Youngs <steve@eicq.org> patch-1
+
+ Summary:
+ Prepare for 0.8 cycle, add previous ChangeLog file
+ Revision:
+ eicq--main--0.8--patch-1
+
+ * Makefile (VER): Bump to 0.8
+
+ * NEWS: Prepare for 0.8
+
+ * eicq.el: Mark version in file's header as 0.8
+
+ * ChangeLog.d/ChangeLog-0.7: New.
+
+
+ new files:
+ ChangeLog.d/.arch-ids/ChangeLog-0.7.id
+ ChangeLog.d/ChangeLog-0.7
+
+ modified files:
+ Makefile NEWS eicq.el
+
+
+2005-06-13 14:57:06 GMT Steve Youngs <steve@eicq.org> base-0
+
+ Summary:
+ tag of steve@eicq.org--2005/eicq--main--0.7--version-0
+ Revision:
+ eicq--main--0.8--base-0
+
+ (automatically generated log message)
+
+ new patches:
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-1
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-2
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-3
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-1
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-2
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-4
+ lg@xwem.org--2005/eicq--lg--0.7--patch-1
+ lg@xwem.org--2005/eicq--lg--0.7--patch-2
+ lg@xwem.org--2005/eicq--lg--0.7--patch-5
+ lg@xwem.org--2005/eicq--lg--0.7--patch-8
+ lg@xwem.org--2005/eicq--lg--0.7--patch-9
+ lg@xwem.org--2005/eicq--lg--0.7--patch-12
+ lg@xwem.org--2005/eicq--lg--0.7--patch-13
+ lg@xwem.org--2005/eicq--lg--0.7--patch-14
+ lg@xwem.org--2005/eicq--lg--0.7--patch-16
+ lg@xwem.org--2005/eicq--lg--0.7--patch-18
+ lg@xwem.org--2005/eicq--lg--0.7--patch-19
+ lg@xwem.org--2005/eicq--lg--0.7--patch-20
+ lg@xwem.org--2005/eicq--lg--0.7--patch-21
+ lg@xwem.org--2005/eicq--lg--0.7--patch-23
+ lg@xwem.org--2005/eicq--lg--0.7--patch-28
+ steve@eicq.org--2004/eicq--main--0.6--base-0
+ steve@eicq.org--2004/eicq--main--0.6--patch-1
+ steve@eicq.org--2004/eicq--main--0.6--patch-2
+ steve@eicq.org--2004/eicq--main--0.6--patch-3
+ steve@eicq.org--2004/eicq--main--0.6--patch-4
+ steve@eicq.org--2004/eicq--main--0.6--patch-5
+ steve@eicq.org--2004/eicq--main--0.6--patch-6
+ steve@eicq.org--2004/eicq--main--0.6--patch-7
+ steve@eicq.org--2004/eicq--main--0.6--patch-8
+ steve@eicq.org--2004/eicq--main--0.6--patch-9
+ steve@eicq.org--2004/eicq--main--0.6--patch-10
+ steve@eicq.org--2004/eicq--main--0.6--patch-11
+ steve@eicq.org--2004/eicq--main--0.6--patch-12
+ steve@eicq.org--2004/eicq--main--0.6--patch-13
+ steve@eicq.org--2004/eicq--main--0.6--patch-14
+ steve@eicq.org--2004/eicq--main--0.6--patch-15
+ steve@eicq.org--2005/eicq--main--0.7--base-0
+ steve@eicq.org--2005/eicq--main--0.7--patch-1
+ steve@eicq.org--2005/eicq--main--0.7--patch-2
+ steve@eicq.org--2005/eicq--main--0.7--patch-3
+ steve@eicq.org--2005/eicq--main--0.7--patch-4
+ steve@eicq.org--2005/eicq--main--0.7--patch-5
+ steve@eicq.org--2005/eicq--main--0.7--patch-6
+ steve@eicq.org--2005/eicq--main--0.7--patch-7
+ steve@eicq.org--2005/eicq--main--0.7--patch-8
+ steve@eicq.org--2005/eicq--main--0.7--patch-9
+ steve@eicq.org--2005/eicq--main--0.7--patch-10
+ steve@eicq.org--2005/eicq--main--0.7--patch-11
+ steve@eicq.org--2005/eicq--main--0.7--patch-12
+ steve@eicq.org--2005/eicq--main--0.7--patch-13
+ steve@eicq.org--2005/eicq--main--0.7--patch-14
+ steve@eicq.org--2005/eicq--main--0.7--patch-15
+ steve@eicq.org--2005/eicq--main--0.7--patch-16
+ steve@eicq.org--2005/eicq--main--0.7--patch-17
+ steve@eicq.org--2005/eicq--main--0.7--patch-18
+ steve@eicq.org--2005/eicq--main--0.7--patch-19
+ steve@eicq.org--2005/eicq--main--0.7--patch-20
+ steve@eicq.org--2005/eicq--main--0.7--patch-21
+ steve@eicq.org--2005/eicq--main--0.7--patch-22
+ steve@eicq.org--2005/eicq--main--0.7--patch-23
+ steve@eicq.org--2005/eicq--main--0.7--patch-24
+ steve@eicq.org--2005/eicq--main--0.7--patch-25
+ steve@eicq.org--2005/eicq--main--0.7--patch-26
+ steve@eicq.org--2005/eicq--main--0.7--patch-27
+ steve@eicq.org--2005/eicq--main--0.7--patch-28
+ steve@eicq.org--2005/eicq--main--0.7--patch-29
+ steve@eicq.org--2005/eicq--main--0.7--patch-30
+ steve@eicq.org--2005/eicq--main--0.7--patch-31
+ steve@eicq.org--2005/eicq--main--0.7--patch-32
+ steve@eicq.org--2005/eicq--main--0.7--patch-33
+ steve@eicq.org--2005/eicq--main--0.7--patch-34
+ steve@eicq.org--2005/eicq--main--0.7--patch-35
+ steve@eicq.org--2005/eicq--main--0.7--patch-36
+ steve@eicq.org--2005/eicq--main--0.7--patch-37
+ steve@eicq.org--2005/eicq--main--0.7--patch-38
+ steve@eicq.org--2005/eicq--main--0.7--patch-39
+ steve@eicq.org--2005/eicq--main--0.7--patch-40
+ steve@eicq.org--2005/eicq--main--0.7--patch-41
+ steve@eicq.org--2005/eicq--main--0.7--patch-42
+ steve@eicq.org--2005/eicq--main--0.7--patch-43
+ steve@eicq.org--2005/eicq--main--0.7--patch-44
+ steve@eicq.org--2005/eicq--main--0.7--patch-45
+ steve@eicq.org--2005/eicq--main--0.7--patch-46
+ steve@eicq.org--2005/eicq--main--0.7--patch-47
+ steve@eicq.org--2005/eicq--main--0.7--patch-48
+ steve@eicq.org--2005/eicq--main--0.7--patch-49
+ steve@eicq.org--2005/eicq--main--0.7--patch-50
+ steve@eicq.org--2005/eicq--main--0.7--patch-51
+ steve@eicq.org--2005/eicq--main--0.7--patch-52
+ steve@eicq.org--2005/eicq--main--0.7--patch-53
+ steve@eicq.org--2005/eicq--main--0.7--patch-54
+ steve@eicq.org--2005/eicq--main--0.7--patch-55
+ steve@eicq.org--2005/eicq--main--0.7--patch-56
+ steve@eicq.org--2005/eicq--main--0.7--patch-57
+ steve@eicq.org--2005/eicq--main--0.7--patch-58
+ steve@eicq.org--2005/eicq--main--0.7--patch-59
+ steve@eicq.org--2005/eicq--main--0.7--patch-60
+ steve@eicq.org--2005/eicq--main--0.7--version-0
+
+
--- /dev/null
+# do not edit -- automatically generated by arch changelog
+# arch-tag: automatic-ChangeLog--steve@eicq.org--2007/eicq--main--0.9.1
+#
+
+2007-11-13 05:30:37 GMT Steve Youngs <steve@eicq.org> version-0
+
+ Summary:
+ End of an era -- Last Eicq Release
+ Revision:
+ eicq--main--0.9.1--version-0
+
+ Sadly, this will be the last Eicq release. But don't worry, because
+ we'll be back very soon in the form of EMchat.
+
+
+2007-11-07 02:39:45 GMT Steve Youngs <steve@eicq.org> patch-43
+
+ Summary:
+ Build chain fixes/improvements
+ Revision:
+ eicq--main--0.9.1--patch-43
+
+ This changeset improves the build chain, with most things now being
+ handled in build.el.
+
+ * .arch-inventory: Add custom-defines.el and prepsrc.el to precious, also
+ make all .rej files unrecognized.
+
+ * Makefile (GENERATED_SRC): New. Lists the generated lisp.
+ (EXTRA_OBJ): Removed, in favour of $GENERATED_OBJ
+ (GENERATED_OBJ): New. Lists the byte-compiled generated
+ lisp.
+ (PRELOADS): Removed, now incorporated in build.el.
+ (all): Rewrite.
+ (compile): Rewrite.
+ (prepsrc.el): New target.
+ (prepsrc): New target.
+ (autoloads,customloads,auto-autoloads.el,custom-load.el): Removed.
+ (install): Use $GENERATED vars.
+ (pkg): Ditto.
+ (clean): Ditto.
+ (distclean): Also remove prepsrc.el
+
+ * build.el: Incorporate the old Makefile $PRELOADS
+ Remove the hard-coded list of files to compile, this is now
+ auto-generated from the Makefile.
+
+ modified files:
+ .arch-inventory Makefile build.el
+
+
+2007-11-06 07:16:34 GMT Steve Youngs <steve@sxemacs.org> patch-42
+
+ Summary:
+ Fix the build, add some more error packets
+ Revision:
+ eicq--main--0.9.1--patch-42
+
+ This changeset fixes, and by "fixes" I of course mean "work around" a bug
+ in current SXEmacs that prevents Eicq from being built.
+
+ Also here are some more error packets.
+
+ * eicq-v8.el (eicq-v8-snac-srv-privacy-err): New packet, SNAC 9,1
+ (eicq-v8-snac-list): Add it.
+ (eicq-v8-valid-incoming-handlers): Add new handler type `srv-error'.
+ (eicq-v8-snac-list): Reorganise, throw in some comments.
+ (eicq-v8-snac-srv-err): Run an incoming handler and get the error
+ message in front of the user where it belongs.
+
+ * eicq.el (eicq-do-srv-general-err): Handle SRV_GEN_ERR.
+ (eicq-login): Add srv-error handler type.
+
+ * eicq-log.el: Autoload #'smiley-region instead of requiring smiley.
+ This works around a problem in current SXEmacs where you can't build
+ lisp with -batch.
+
+
+ modified files:
+ eicq-log.el eicq-v8.el eicq.el
+
+
+2007-11-05 08:56:31 GMT Steve Youngs <steve@sxemacs.org> patch-41
+
+ Summary:
+ New packet (SNAC 3,1) and build chain tweaks
+ Revision:
+ eicq--main--0.9.1--patch-41
+
+ This changeset adds a new packet SRV_CONTACTERR (SNAC 3,1). And it also
+ tweaks the build chain a bit, moving to a more pure elisp based chain.
+
+ * eicq-v8.el (eicq-v8-fetch-uinlist): New fetcher.
+ (eicq-v8-snac-srv-contact-err): New packet.
+
+ * eicq.el (eicq-do-srv-contact-err): New.
+
+ * eicq.el (eicq-login): Add srv-contacterr handler.
+
+ * build.el: New file to handle the build. elisp is easier to work with
+ for me than makefiles are.
+
+ * eicq-curl.el (eicq-curl-post-hook): Use `t' instead of `otherwise' in
+ the #'cond call. `otherwise' is broken in SXEmacs atm.
+
+ * Makefile (all): Let the new build.el handle it.
+
+ * Makefile (autoloads): Ditto.
+
+
+ new files:
+ .arch-ids/build.el.id build.el
+
+ modified files:
+ Makefile eicq-curl.el eicq-v8.el eicq.el
+
+
+2007-09-21 23:19:35 GMT Steve Youngs <steve@eicq.org> patch-40
+
+ Summary:
+ Fix sloppy text emphasis
+ Revision:
+ eicq--main--0.9.1--patch-40
+
+ * eicq-log.el (eicq-log-mode-syntax-table): Don't include the emphasis
+ tags as word-constituents.
+
+
+ modified files:
+ eicq-log.el
+
+
+2007-09-05 01:51:02 GMT Steve Youngs <steve@eicq.org> patch-39
+
+ Summary:
+ Humanise eicq-curl output
+ Revision:
+ eicq--main--0.9.1--patch-39
+
+ This changeset makes the output from eicq-curl a bit nicer. File sizes
+ and transfer speeds are shown in gigabytes, megabytes, kilobytes, bytes,
+ depending on size/speed.
+
+ * eicq-curl.el (eicq-curl-post-hook): Show size and speed in a more human
+ readable form.
+
+
+ modified files:
+ eicq-curl.el
+
+
+2007-09-03 10:09:33 GMT Steve Youngs <steve@eicq.org> patch-38
+
+ Summary:
+ More history tweaks plus nuke insane keybindings
+ Revision:
+ eicq--main--0.9.1--patch-38
+
+ * eicq-log.el (eicq-log-update-history): Make sure !debug, !error, !info,
+ !debug histories are still tracked.
+
+ * eicq-menu.el (eicq-main-map): Remove the silly `1' and `2' keybindings.
+
+
+ modified files:
+ eicq-log.el eicq-menu.el
+
+
+2007-09-03 07:37:42 GMT Steve Youngs <steve@eicq.org> patch-37
+
+ Summary:
+ Block more boring stuff from the history files.
+ Revision:
+ eicq--main--0.9.1--patch-37
+
+ This and the previous changeset should reduce the amount of useless crap
+ spamming your history files. Status changes aren't tracked in the
+ history files and no history is saved for people you should be invisible
+ to.
+
+ * eicq-log.el (eicq-log-update-history): Don't save histories for people
+ you should be invisible to.
+
+
+ modified files:
+ eicq-log.el
+
+
+2007-09-03 07:05:24 GMT Steve Youngs <steve@eicq.org> patch-36
+
+ Summary:
+ Don't log status changes in the history files
+ Revision:
+ eicq--main--0.9.1--patch-36
+
+ * eicq-log.el (eicq-log-update-history): Don't notice status changes and
+ other boring things in the history files.
+
+
+ modified files:
+ eicq-log.el
+
+
+2007-09-01 12:08:04 GMT Steve Youngs <steve@eicq.org> patch-35
+
+ Summary:
+ Fix a byte-compiler warning
+ Revision:
+ eicq--main--0.9.1--patch-35
+
+ * eicq-curl.el: Fix byte-compiler warning.
+
+
+ modified files:
+ eicq-curl.el
+
+
+2007-09-01 12:03:44 GMT Steve Youngs <steve@eicq.org> patch-34
+
+ Summary:
+ Enhance eicq-curl output
+ Revision:
+ eicq--main--0.9.1--patch-34
+
+ This changeset takes advantage of the brand new `worker job plists' just
+ introduced into SXEmacs. It gives the output to the log buffer a little
+ more verbosity. Gotta love eye-candy.
+
+ * eicq-curl.el (eicq-curl-post-hook): Make the output more verbose using
+ data from the job's plist.
+ (eicq-curl-filename-regexp): Make it a defregexp if in SXEmacs.
+ (eicq-curl-url-at-point): No need to set a global var for the url, it
+ is now accessible via the job's plist.
+ (eicq-curl-url-at-mouse): Ditto.
+
+
+ modified files:
+ eicq-curl.el
+
+
+2007-09-01 03:00:30 GMT Steve Youngs <steve@eicq.org> patch-33
+
+ Summary:
+ _Really_ fix emphasis
+ Revision:
+ eicq--main--0.9.1--patch-33
+
+ This changeset hopefully completely fixes emphasis, and makes it a lot
+ better. Emphasising text that includes punctuation will now work.
+
+
+ * eicq-log.el (eicq-log-mode-syntax-table): New. Same as
+ `text-mode-syntax-table' except all the punctuation chars are word
+ constituents. This lets emphasis work when punctuation is used within
+ the emphasised tags.
+ (eicq-log-mode): Use it.
+ (eicq-log-update-tracker): Allow for the informational messages now
+ being prefixed with `***|' instead of `***'.
+
+ * eicq-status.el (eicq-buddy-update-status): Prefix messages with `***|'
+ instead of `***' to cater for the emphasis changes.
+ (eicq-turn-on-invisibility): Ditto.
+ (eicq-turn-off-invisibility): Ditto.
+
+
+ modified files:
+ eicq-log.el eicq-status.el
+
+
+2007-09-01 01:47:51 GMT Steve Youngs <steve@eicq.org> patch-32
+
+ Summary:
+ Fix log eye-candy.
+ Revision:
+ eicq--main--0.9.1--patch-32
+
+ This changeset fixes the bug where if you emphasised some text that
+ contained punctuation... the emphasis would not be added.
+
+ * eicq-log.el (eicq-log-mode): Use text-mode's syntax-table
+
+
+ modified files:
+ eicq-log.el
+
+
+2007-09-01 00:29:32 GMT Steve Youngs <steve@eicq.org> patch-31
+
+ Summary:
+ Forgot to actually add the new files :-(
+ Revision:
+ eicq--main--0.9.1--patch-31
+
+
+ new files:
+ .arch-ids/eicq-curl.el.id .arch-ids/eicq-utils.el.id
+ eicq-curl.el eicq-utils.el
+
+
+2007-09-01 00:10:14 GMT Steve Youngs <steve@eicq.org> patch-30
+
+ Summary:
+ Fix upgrade Makefile target.
+ Revision:
+ eicq--main--0.9.1--patch-30
+
+ * Makefile (upgrade): Do a distclean here first.
+
+
+ modified files:
+ Makefile
+
+
+2007-08-31 23:56:33 GMT Steve Youngs <steve@eicq.org> patch-29
+
+ Summary:
+ Implement URL downloading from log buffer + minor build tweaks
+ Revision:
+ eicq--main--0.9.1--patch-29
+
+ This changeset allows for downloading URLs in the log buffer to files
+ locally via #'curl:download&. OK, that means you need SXEmacs for this
+ to work.
+
+ There are also some minor build tweaks and rearrangements.
+
+ * Makefile (SOURCES): Add eicq-utils.el, eicq-curl.el.
+
+ * eicq-emphasis.el (eicq-emphasis-alist): Hide the `*' bold tags.
+
+ * eicq-log.el: Require eicq-curl.
+ (eicq-log-system): Run the eicq-system-message hooks here.
+
+ * eicq-menu.el: Require eicq-utils, change all define-keys to use #'func
+ naming syntax.
+ (eicq-hyperlink-map): Add bindings for eicq-curl.
+
+ * eicq-report.el (eicq-report-debug): Add eicq-curl.el.
+
+ * eicq-xwem.el: Add our secret bug-reporter "cookie".
+
+ * eicq.el: Require eicq-utils.
+ (eicq-do-in-xemacs): Moved to eicq-utils.el
+ (eicq-do-in-sxemacs): Ditto.
+ (eicq-completing-read): Ditto.
+ (eicq-numeric-uin): Ditto.
+ (eicq-stringular-uin): Ditto.
+ (eicq-valid-uin-p): Ditto.
+ (eicq-completing-aliases): Ditto.
+ (eicq-completing-alias): Ditto.
+ (eicq-switch-buffer): Ditto.
+
+ * eicq-curl.el: New. Download URLs from the log buffer.
+
+ * eicq-utils.el: New. Where any general utils should go.
+
+ modified files:
+ Makefile eicq-emphasis.el eicq-log.el eicq-menu.el
+ eicq-report.el eicq-xwem.el eicq.el
+
+
+2007-08-18 06:44:07 GMT Steve Youngs <steve@eicq.org> patch-28
+
+ Summary:
+ Stop server from dropping parts of large outgoing msgs
+ Revision:
+ eicq--main--0.9.1--patch-28
+
+ This changeset makes it possible to send very long messages without the
+ server dropping part or all of the message.
+
+ * eicq.el (eicq-message-max-size): Increase to 500.
+ (eicq-splitter): This was renamed from `eicq-spliter'.
+ (eicq-send-message): Add a delay between message parts of a large
+ message so that the server doesn't drop part or all of the sent
+ message.
+
+
+ modified files:
+ eicq.el
+
+
+2007-08-17 22:13:52 GMT Steve Youngs <steve@eicq.org> patch-27
+
+ Summary:
+ Guard against empty slots creeping into eicq-(in)visible-contacts list
+ Revision:
+ eicq--main--0.9.1--patch-27
+
+ * eicq.el (eicq-remove-from-visible-list): Don't leave empty slots in the
+ list.
+ (eicq-remove-from-invisible-list): Ditto.
+
+
+ modified files:
+ eicq.el
+
+
+2007-08-16 14:43:32 GMT Steve Youngs <steve@eicq.org> patch-26
+
+ Summary:
+ Add some sexiness to the balloon-help buffers.
+ Revision:
+ eicq--main--0.9.1--patch-26
+
+ Pure eye-candy!
+
+ * eicq-buddy.el (eicq-buddy-show-xface-in-balloon): New. For displaying
+ X-Face images in balloon-help.
+ (balloon-help-display-help): Advised to insert the X-Face image.
+ (eicq-buddy-update-face): Slightly modify the balloon-help text to
+ cater for X-Face images. Basically add a bit of whitespace at the
+ end.
+
+ * eicq-log.el (eicq-log-update-balloon): Ditto.
+
+
+ modified files:
+ eicq-buddy.el eicq-log.el
+
+
+2007-08-14 02:47:23 GMT Steve Youngs <steve@eicq.org> patch-25
+
+ Summary:
+ Improve automatic/idle messages
+ Revision:
+ eicq--main--0.9.1--patch-25
+
+ This changeset improves and enhances the automatic messages, stuff like
+ the auto response you send out when you receive a msg while you are away,
+ na, dnd, or occ.
+
+ These outgoing messages are now sent as `automatic' message type. Care
+ has been taken to ensure that only people who are on your visible list or
+ not on your invisible list will ever get these messages.
+
+ We now handle incoming `automatic' messages, as well as incoming requests
+ for your away, na, dnd, occ message.
+
+ Also, you can now request that an ICQ user's client send you its away,
+ na, dnd, or occ message.
+
+ New user functions:
+ ==================
+
+ #'eicq-request-away -- Request a user's away message.
+ #'eicq-request-na -- Request a user's na message.
+ #'eicq-request-dnd -- Request a user's dnd message.
+ #'eicq-request-occ -- Request a user's occ message.
+
+
+ * eicq.el (eicq-message-types): Removed. Obsolete.
+ (eicq-pack-add-user-to-contact-list): Ditto.
+ (eicq-idle-reply-maybe): Ensure idle replies don't go out to members of
+ your invisible list or those not on your visible list.
+ (eicq-do-message-helper): Add `automatic', `get-away', `get-na',
+ `get-occ', `get-dnd' message types.
+ (eicq-auto-reply): Send as `automatic' message type.
+ (eicq-idle-reply): Ditto.
+ (eicq-request-away): New. Request a contact's "away" message.
+ (eicq-request-na): Ditto, "na" message.
+ (eicq-request-dnd): Ditto. "dnd" message.
+ (eicq-request-occ): Ditto. "occ" message.
+
+
+ modified files:
+ eicq.el
+
+
+2007-08-12 23:54:55 GMT Steve Youngs <steve@eicq.org> patch-24
+
+ Summary:
+ Sound enhancement... customisable media driver
+ Revision:
+ eicq--main--0.9.1--patch-24
+
+ This changeset gives SXEmacs users the option of specifying a driver to
+ use for creating the media streams. It also gives me a way to work
+ around a problem I currently have with ffmpeg. :-)
+
+ * eicq.el (eicq-media-driver): New. To specify the driver to use when
+ creating the streams.
+ (eicq-load-media-streams): Use it.
+
+
+ modified files:
+ eicq.el
+
+
+2007-08-11 15:03:41 GMT Steve Youngs <steve@eicq.org> patch-23
+
+ Summary:
+ Fix auto reply message sending in regards to visible/invisible lists.
+ Revision:
+ eicq--main--0.9.1--patch-23
+
+ * eicq.el (eicq-auto-reply-maybe): Don't send auto replies to people who
+ should be unable to see you on the network.
+
+
+ modified files:
+ eicq.el
+
+
+2007-08-11 14:03:51 GMT Steve Youngs <steve@sxemacs.org> patch-22
+
+ Summary:
+ Introduce visible/invisible lists
+ Revision:
+ eicq--main--0.9.1--patch-22
+
+ This changeset introduces "visible" and "invisible" lists to Eicq. If
+ you have contacts on a visible list, then anyone who _isn't_ on the list
+ will not be able to see you on the ICQ network. Likewise for a invisible
+ list, anyone _not_ on the list _can_ see you.
+
+ The default setting is to have no invisible list, and to have all of your
+ contacts in eicq-world on your visible list. This means that only people
+ on your contact list will be able to see you. If you want to be
+ invisible to someone in your contact list, just add them to your
+ invisible list. They can remain on your visible list without causing any
+ problems because the invisible list is sent _after_ the visible.
+
+ New user-customisable variables...
+
+ eicq-visible-contacts -- Defaults to all contacts in eicq-world, most
+ users probably won't need to change this.
+
+ eicq-invisible-contacts -- Defaults to nil. Put your idiots here.
+
+ New user commands...
+
+ #'eicq-add-to-visible-list
+ #'eicq-add-to-invisible-list
+ #'eicq-remove-from-visible-list
+ #'eicq-remove-from-invisible-list
+
+ * eicq-v8.el (eicq-v8-snac-cli-addvisible): New. Add contacts to visible
+ list.
+ (eicq-v8-snac-cli-remvisible): New. Remove contacts from visible list.
+ (eicq-v8-snac-cli-addinvisible): New. Add contacts to invisible list.
+ (eicq-v8-snac-cli-reminvisible): New. Remove contacts from invisible
+ list.
+ (eicq-v8-snac-list): Add visible/invisible packets.
+
+ * eicq.el (eicq-visible-contacts): New. List of contacts that are added
+ to the "visible" list at login. Default is everyone on your contact
+ list.
+ (eicq-invisible-contacts): New. As above, but for the "invisible"
+ list.
+ (eicq-send-contact-list): Send visible/invisible lists.
+ (eicq-init-visible-list): Used to initialise `eicq-visible-contacts'.
+ (eicq-add-to-visible-list): New. Interactively add contacts to visible
+ list.
+ (eicq-add-to-invisible-list): New. As above, but for invisible list.
+ (eicq-remove-from-visible-list): New. Interactively remove contacts
+ from visible list.
+ (eicq-remove-from-invisible-list): New. As above, but for invisible
+ list.
+
+
+
+ modified files:
+ eicq-v8.el eicq.el
+
+
+2007-08-09 09:29:30 GMT Steve Youngs <steve@eicq.org> patch-21
+
+ Summary:
+ Fix type 4 messages
+ Revision:
+ eicq--main--0.9.1--patch-21
+
+ This changeset fixes type 4 messages... things like URL messages and auth
+ request/accept/reject. The TLVs in these messages are now coming from
+ the server in reverse order. Gotta love them AOL lunatics.
+
+ * eicq-v8.el (eicq-v8-snac-srv-recv-msg): Reverse the tlv list for type 4
+ messages.
+
+
+ modified files:
+ eicq-v8.el
+
+
+2007-08-08 15:14:10 GMT Steve Youngs <steve@eicq.org> patch-20
+
+ Summary:
+ Protect uninitialised defvar's
+ Revision:
+ eicq--main--0.9.1--patch-20
+
+ This changeset protects all the uninitialised defvar's from the
+ interpreter by wrapping them in a #'eval-when-compile.
+
+ * eicq.el: Move all uninitialised defvar's under a #'eval-when-compile.
+
+ * eicq-log.el: Ditto.
+
+ * eicq-world.el: Ditto.
+
+
+ modified files:
+ eicq-log.el eicq-world.el eicq.el
+
+
+2007-08-08 01:08:58 GMT Steve Youngs <steve@eicq.org> patch-19
+
+ Summary:
+ Sound fix... make sure the stream symbols get created
+ Revision:
+ eicq--main--0.9.1--patch-19
+
+ This changeset fixes a problem introduced with Sebastian's last change.
+ If the media stream symbols did not already exist, they would never be
+ created.
+
+ * eicq.el (eicq-load-media-streams): Use #'intern instead of
+ #'intern-soft. This time we _want_ the symbol to be created.
+
+
+ modified files:
+ eicq.el
+
+
+2007-08-08 00:02:56 GMT Steve Youngs <steve@eicq.org> patch-18
+
+ Summary:
+ Minor tweak to the sound.
+ Revision:
+ eicq--main--0.9.1--patch-18
+
+ * eicq.el (eicq-login): Don't call #'eicq-load-media-streams
+ interactively.
+
+ modified files:
+ eicq.el
+
+
+2007-08-07 22:26:53 GMT Steve Youngs <steve@eicq.org> patch-17
+
+ Summary:
+ Merged from hrop (patch 4) -- sound fix
+ Revision:
+ eicq--main--0.9.1--patch-17
+
+ Patches applied:
+
+ * hroptatyr@eicq.org--eicq/eicq--hrop--0.9.1--patch-4
+ fix, bind stream symbol rather than the stream object
+
+ modified files:
+ eicq.el
+
+ new patches:
+ hroptatyr@eicq.org--eicq/eicq--hrop--0.9.1--patch-4
+
+
+2007-08-07 14:12:02 GMT Steve Youngs <steve@eicq.org> patch-16
+
+ Summary:
+ Sound fixes/improvements
+ Revision:
+ eicq--main--0.9.1--patch-16
+
+ This changeset fixes hopefully the last of the sound issues. It also
+ allows SXEmacs users to specify a separate audio device for Eicq. For
+ example, a SXEmacs user with PulseAudio might...
+
+ ,----[ example ]
+ | (setq eicq-audio-device
+ | (make-audio-device 'pulse :server "some.remote.host"
+ | :client "SXEmacs::Eicq"
+ | :stream "Eicq::Stream"
+ | :force t))
+ `----
+
+ * eicq.el (eicq-audio-device): New. The audio device where we play
+ sounds in SXEmacs. Defaults to `default-audio-device'.
+ (eicq-play-sound-maybe): Use it. Plus, guard against unbound symbols.
+ (eicq-load-media-streams): Guard against unbound symbols.
+
+
+ modified files:
+ eicq.el
+
+
+2007-08-07 04:40:09 GMT Steve Youngs <steve@eicq.org> patch-15
+
+ Summary:
+ More sound fixes fixing the last fix.
+ Revision:
+ eicq--main--0.9.1--patch-15
+
+ This changeset some minor fixes to the new sound stuff, and we stop
+ getting the user's home directory from the environment, instead we use
+ #'user-home-directory.
+
+ * eicq.el (eicq-directory): Use #'user-home-directory instead of env var
+ $HOME.
+ (eicq-load-media-streams): Use #'intern-soft when testing if the stream
+ exists so we don't create the symbol unneccessarily.
+ (eicq-play-sound-maybe): Use #'intern-soft instead of #'intern for the
+ same reason.
+ (eicq-login): Load the media streams.
+
+ * eicq-convert.el (eicq-import-from-micq): Use #'user-home-directory
+ instead of env var $HOME.
+
+ * Makefile: Nuke a stupid comment.
+
+
+ modified files:
+ Makefile eicq-convert.el eicq.el
+
+
+2007-08-07 02:40:08 GMT Steve Youngs <steve@eicq.org> patch-14
+
+ Summary:
+ Sound improvements/fixes
+ Revision:
+ eicq--main--0.9.1--patch-14
+
+ This changeset vastly improves the sound code for Eicq on SXEmacs. In
+ days of olde we'd create each media stream on the fly, _every_ time a
+ sound was played. Not only was that incredibly inefficient, but it was
+ possible for SXEmacs to dump core if too many sounds were played
+ simultaneously because the garbage collector was getting in a tizzy over
+ it.
+
+ What we do now is create all the needed media streams _once_ and save
+ them for future use. This reduces the amount of processing required
+ because we're only creating each stream once instead of every time a
+ sound is played. But more importantly, saving the streams prevents them
+ from being gc'd away.
+
+ There's also a couple of minor build time fixes.
+
+ * eicq.el (eicq-use-sound-flag): Switch it to a normal boolean var.
+ (eicq-play-sound-maybe): New. Renamed from `eicq-maybe-play-sound'.
+ This version doesn't create media streams on the fly in SXEmacs as they
+ are already created/loaded.
+ (eicq-do-message-helper): Use #'eicq-play-sound-maybe instead of
+ #'eicq-maybe-play-sound.
+ (eicq-load-media-streams): New. Loads/saves the media streams in
+ SXEmacs. This lets the streams be created once or when you explicitly
+ want them recreated. Saves us a truck load of processing time, and is
+ a hell of a lot safer.
+
+ * eicq-status.el (eicq-buddy-update-status): Use #'eicq-play-sound-maybe
+ instead of #'eicq-maybe-play-sound.
+
+ * eicq-xwem.el: Add some missing autoloads at compile time.
+
+
+ modified files:
+ eicq-status.el eicq-xwem.el eicq.el
+
+
+2007-07-21 15:00:23 GMT Steve Youngs <steve@eicq.org> patch-13
+
+ Summary:
+ Merged from lg (patch 9) -- couple of minor fixes
+ Revision:
+ eicq--main--0.9.1--patch-13
+
+ Patches applied:
+
+ * lg@xwem.org--2007/eicq--lg--0.9--patch-9
+ small fixes
+
+ modified files:
+ eicq-v8.el eicq.el
+
+ new patches:
+ lg@xwem.org--2007/eicq--lg--0.9--patch-9
+
+
+2007-07-09 13:38:07 GMT Steve Youngs <steve@eicq.org> patch-12
+
+ Summary:
+ Fix unnecessary spamming of log buffer during login
+ Revision:
+ eicq--main--0.9.1--patch-12
+
+ This changeset fixes a problem AOL introduced today that was causing
+ every contact in your contact list to be logged as "offline" when you
+ logged in. Reasonably harmless, but very annoying.
+
+ * eicq-status.el (eicq-buddy-update-status): Work around the latest
+ protocol change.
+
+
+ modified files:
+ eicq-status.el
+
+
+2007-06-30 15:54:21 GMT Steve Youngs <steve@eicq.org> patch-11
+
+ Summary:
+ Improve explanation of world syntax
+ Revision:
+ eicq--main--0.9.1--patch-11
+
+ * eicq-setup.el (eicq-world-user-file-template): Improve wording and
+ syntax explanation.
+
+ * INSTALL: Include a copy of the template world file from eicq-setup.el
+
+
+ modified files:
+ INSTALL eicq-setup.el
+
+
+2007-05-01 16:03:40 GMT Steve Youngs <steve@eicq.org> patch-10
+
+ Summary:
+ Merged from lg (patch 5) - XWEM OSD update
+ Revision:
+ eicq--main--0.9.1--patch-10
+
+ Patches applied:
+
+ * lg@xwem.org--2007/eicq--lg--0.9--patch-5
+ more features for OSD, dock now optional
+
+ modified files:
+ eicq-xwem.el
+
+ new patches:
+ lg@xwem.org--2007/eicq--lg--0.9--patch-5
+
+
+2007-04-24 23:34:26 GMT Steve Youngs <steve@eicq.org> patch-9
+
+ Summary:
+ Merged from lg (patch 4) -- XWEM dock update.
+ Revision:
+ eicq--main--0.9.1--patch-9
+
+ Patches applied:
+
+ * lg@xwem.org--2007/eicq--lg--0.9--patch-4
+ Adds keymap to dock and creates messages OSD.
+
+ modified files:
+ eicq-v8.el eicq-xwem.el
+
+ new patches:
+ lg@xwem.org--2007/eicq--lg--0.9--patch-4
+
+
+2007-02-08 09:44:40 GMT Steve Youngs <steve@eicq.org> patch-8
+
+ Summary:
+ Fix alias selection/deselection
+ Revision:
+ eicq--main--0.9.1--patch-8
+
+ This changeset fixes alias/buddy selection, making it possible to
+ deselect a selected alias
+
+ * eicq-world.el (eicq-group-select-aliases): Fix select/deselect
+ aliases.
+
+
+ modified files:
+ eicq-world.el
+
+
+2007-02-05 01:16:24 GMT Steve Youngs <steve@eicq.org> patch-7
+
+ Summary:
+ Play system sound when SRV_MISSED_ICBM comes in.
+ Revision:
+ eicq--main--0.9.1--patch-7
+
+ * eicq.el (eicq-do-message-helper): Play a sound for missed messages.
+
+
+ modified files:
+ eicq.el
+
+
+2007-02-05 00:52:42 GMT Steve Youngs <steve@eicq.org> patch-6
+
+ Summary:
+ Tweak missed message handling, call the hook with args.
+ Revision:
+ eicq--main--0.9.1--patch-6
+
+ This changeset improves the handling of missed messages a bit. The hook,
+ `eicq-missed-message-hook' is now called with ALIAS, NUM, REASON as args
+ using `run-hook-with-args'.
+
+ * eicq.el (eicq-do-missed-message): Rename local var UIN -> ALIAS, makes
+ more sense to me.
+ Call `eicq-missed-message-hook' using `run-hook-with-args' and pass
+ along ALIAS, NUM, and REASON.
+ (eicq-missed-message-hook): Document the args passed.
+
+
+ modified files:
+ eicq.el
+
+
+2007-02-04 23:23:32 GMT Steve Youngs <steve@eicq.org> patch-5
+
+ Summary:
+ Merged from lg (patch 2-3) -- Handle SRV_MISSED_ICBM SNAC(4, 10)
+ Revision:
+ eicq--main--0.9.1--patch-5
+
+ This changeset implements SRV_MISSED_ICBM SNAC(4, 10). This is the
+ packet you get if incoming messages exceed your rate limit. It also
+ runs a `eicq-missed-messages-hook' which can be used to send a "please
+ resend" back to the sender if you want.
+
+ * eicq.el (eicq-do-missed-message): Add message type arg to
+ `eicq-do-message-helper' call.
+ Send a "please resend" message back to the sender.
+ (eicq-do-message-helper): Handle SRV_MISSED_ICBM SNAC 4, 10.
+ (eicq-missed-message-hook): New hook run from
+ `eicq-do-missed-message'.
+
+ Patches applied:
+
+ * lg@xwem.org--2007/eicq--lg--0.9--patch-2
+ SNAC(4, 10), however needs review and fix by Steve
+
+ * lg@xwem.org--2007/eicq--lg--0.9--patch-3
+ fix fetching tlvs in snac 4, 10
+
+ modified files:
+ eicq-v8.el eicq.el
+
+ new patches:
+ lg@xwem.org--2007/eicq--lg--0.9--patch-2
+ lg@xwem.org--2007/eicq--lg--0.9--patch-3
+
+
+2007-02-04 03:48:50 GMT Steve Youngs <steve@eicq.org> patch-4
+
+ Summary:
+ Better default for eicq-coding-system
+ Revision:
+ eicq--main--0.9.1--patch-4
+
+ This changeset should make the Russians, Europeans, and Aussies happy.
+ Apparently, `cyrillic' in ICQ speak is `windows-1251'...
+
+ * eicq.el (eicq-coding-system): If default buffer coding is cyrillic, use
+ 'windows-1251.
+
+
+ modified files:
+ eicq.el
+
+
+2007-01-26 15:36:19 GMT Steve Youngs <steve@eicq.org> patch-3
+
+ Summary:
+ Fix coding system bug
+ Revision:
+ eicq--main--0.9.1--patch-3
+
+ This changeset fixes a coding-system bug which was stuffing up accented
+ characters in messages. Especially characters with umlauts found in most
+ European languages.
+
+ * eicq.el (eicq-coding-system): Default to
+ `default-buffer-file-coding-system' if mule or file-coding is
+ available, otherwise default to `nil'.
+
+
+ modified files:
+ eicq.el
+
+
+2007-01-17 15:47:22 GMT Steve Youngs <steve@eicq.org> patch-2
+
+ Summary:
+ bump version in Makefile
+ Revision:
+ eicq--main--0.9.1--patch-2
+
+
+ modified files:
+ Makefile
+
+
+2007-01-17 15:02:33 GMT Steve Youngs <steve@eicq.org> patch-1
+
+ Summary:
+ Add previous version's ChangeLog
+ Revision:
+ eicq--main--0.9.1--patch-1
+
+ OK, so I never intended to have a minor minor release, but I do want Eicq
+ to have a complete implementation of the ICQ protocol before 1.0. So
+ here we are at 0.9.1
+
+ * ChangeLog.d/ChangeLog-0.9: Added from previous version.
+
+
+ new files:
+ ChangeLog.d/.arch-ids/ChangeLog-0.9.id
+ ChangeLog.d/ChangeLog-0.9
+
+
+2007-01-17 14:33:26 GMT Steve Youngs <steve@eicq.org> base-0
+
+ Summary:
+ tag of steve@eicq.org--2006/eicq--main--0.9--patch-15
+ Revision:
+ eicq--main--0.9.1--base-0
+
+ (automatically generated log message)
+
+ new patches:
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-1
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-2
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-3
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-1
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-2
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-4
+ lg@xwem.org--2005/eicq--lg--0.7--patch-1
+ lg@xwem.org--2005/eicq--lg--0.7--patch-2
+ lg@xwem.org--2005/eicq--lg--0.7--patch-5
+ lg@xwem.org--2005/eicq--lg--0.7--patch-8
+ lg@xwem.org--2005/eicq--lg--0.7--patch-9
+ lg@xwem.org--2005/eicq--lg--0.7--patch-12
+ lg@xwem.org--2005/eicq--lg--0.7--patch-13
+ lg@xwem.org--2005/eicq--lg--0.7--patch-14
+ lg@xwem.org--2005/eicq--lg--0.7--patch-16
+ lg@xwem.org--2005/eicq--lg--0.7--patch-18
+ lg@xwem.org--2005/eicq--lg--0.7--patch-19
+ lg@xwem.org--2005/eicq--lg--0.7--patch-20
+ lg@xwem.org--2005/eicq--lg--0.7--patch-21
+ lg@xwem.org--2005/eicq--lg--0.7--patch-23
+ lg@xwem.org--2005/eicq--lg--0.7--patch-28
+ lg@xwem.org--2005/eicq--lg--0.8--patch-1
+ lg@xwem.org--2005/eicq--lg--0.8--patch-2
+ lg@xwem.org--2005/eicq--lg--0.8--patch-3
+ lg@xwem.org--2005/eicq--lg--0.8--patch-4
+ lg@xwem.org--2007/eicq--lg--0.9--patch-1
+ steve@eicq.org--2004/eicq--main--0.6--base-0
+ steve@eicq.org--2004/eicq--main--0.6--patch-1
+ steve@eicq.org--2004/eicq--main--0.6--patch-2
+ steve@eicq.org--2004/eicq--main--0.6--patch-3
+ steve@eicq.org--2004/eicq--main--0.6--patch-4
+ steve@eicq.org--2004/eicq--main--0.6--patch-5
+ steve@eicq.org--2004/eicq--main--0.6--patch-6
+ steve@eicq.org--2004/eicq--main--0.6--patch-7
+ steve@eicq.org--2004/eicq--main--0.6--patch-8
+ steve@eicq.org--2004/eicq--main--0.6--patch-9
+ steve@eicq.org--2004/eicq--main--0.6--patch-10
+ steve@eicq.org--2004/eicq--main--0.6--patch-11
+ steve@eicq.org--2004/eicq--main--0.6--patch-12
+ steve@eicq.org--2004/eicq--main--0.6--patch-13
+ steve@eicq.org--2004/eicq--main--0.6--patch-14
+ steve@eicq.org--2004/eicq--main--0.6--patch-15
+ steve@eicq.org--2005/eicq--main--0.7--base-0
+ steve@eicq.org--2005/eicq--main--0.7--patch-1
+ steve@eicq.org--2005/eicq--main--0.7--patch-2
+ steve@eicq.org--2005/eicq--main--0.7--patch-3
+ steve@eicq.org--2005/eicq--main--0.7--patch-4
+ steve@eicq.org--2005/eicq--main--0.7--patch-5
+ steve@eicq.org--2005/eicq--main--0.7--patch-6
+ steve@eicq.org--2005/eicq--main--0.7--patch-7
+ steve@eicq.org--2005/eicq--main--0.7--patch-8
+ steve@eicq.org--2005/eicq--main--0.7--patch-9
+ steve@eicq.org--2005/eicq--main--0.7--patch-10
+ steve@eicq.org--2005/eicq--main--0.7--patch-11
+ steve@eicq.org--2005/eicq--main--0.7--patch-12
+ steve@eicq.org--2005/eicq--main--0.7--patch-13
+ steve@eicq.org--2005/eicq--main--0.7--patch-14
+ steve@eicq.org--2005/eicq--main--0.7--patch-15
+ steve@eicq.org--2005/eicq--main--0.7--patch-16
+ steve@eicq.org--2005/eicq--main--0.7--patch-17
+ steve@eicq.org--2005/eicq--main--0.7--patch-18
+ steve@eicq.org--2005/eicq--main--0.7--patch-19
+ steve@eicq.org--2005/eicq--main--0.7--patch-20
+ steve@eicq.org--2005/eicq--main--0.7--patch-21
+ steve@eicq.org--2005/eicq--main--0.7--patch-22
+ steve@eicq.org--2005/eicq--main--0.7--patch-23
+ steve@eicq.org--2005/eicq--main--0.7--patch-24
+ steve@eicq.org--2005/eicq--main--0.7--patch-25
+ steve@eicq.org--2005/eicq--main--0.7--patch-26
+ steve@eicq.org--2005/eicq--main--0.7--patch-27
+ steve@eicq.org--2005/eicq--main--0.7--patch-28
+ steve@eicq.org--2005/eicq--main--0.7--patch-29
+ steve@eicq.org--2005/eicq--main--0.7--patch-30
+ steve@eicq.org--2005/eicq--main--0.7--patch-31
+ steve@eicq.org--2005/eicq--main--0.7--patch-32
+ steve@eicq.org--2005/eicq--main--0.7--patch-33
+ steve@eicq.org--2005/eicq--main--0.7--patch-34
+ steve@eicq.org--2005/eicq--main--0.7--patch-35
+ steve@eicq.org--2005/eicq--main--0.7--patch-36
+ steve@eicq.org--2005/eicq--main--0.7--patch-37
+ steve@eicq.org--2005/eicq--main--0.7--patch-38
+ steve@eicq.org--2005/eicq--main--0.7--patch-39
+ steve@eicq.org--2005/eicq--main--0.7--patch-40
+ steve@eicq.org--2005/eicq--main--0.7--patch-41
+ steve@eicq.org--2005/eicq--main--0.7--patch-42
+ steve@eicq.org--2005/eicq--main--0.7--patch-43
+ steve@eicq.org--2005/eicq--main--0.7--patch-44
+ steve@eicq.org--2005/eicq--main--0.7--patch-45
+ steve@eicq.org--2005/eicq--main--0.7--patch-46
+ steve@eicq.org--2005/eicq--main--0.7--patch-47
+ steve@eicq.org--2005/eicq--main--0.7--patch-48
+ steve@eicq.org--2005/eicq--main--0.7--patch-49
+ steve@eicq.org--2005/eicq--main--0.7--patch-50
+ steve@eicq.org--2005/eicq--main--0.7--patch-51
+ steve@eicq.org--2005/eicq--main--0.7--patch-52
+ steve@eicq.org--2005/eicq--main--0.7--patch-53
+ steve@eicq.org--2005/eicq--main--0.7--patch-54
+ steve@eicq.org--2005/eicq--main--0.7--patch-55
+ steve@eicq.org--2005/eicq--main--0.7--patch-56
+ steve@eicq.org--2005/eicq--main--0.7--patch-57
+ steve@eicq.org--2005/eicq--main--0.7--patch-58
+ steve@eicq.org--2005/eicq--main--0.7--patch-59
+ steve@eicq.org--2005/eicq--main--0.7--patch-60
+ steve@eicq.org--2005/eicq--main--0.7--version-0
+ steve@eicq.org--2005/eicq--main--0.8--base-0
+ steve@eicq.org--2005/eicq--main--0.8--patch-1
+ steve@eicq.org--2005/eicq--main--0.8--patch-2
+ steve@eicq.org--2005/eicq--main--0.8--patch-3
+ steve@eicq.org--2005/eicq--main--0.8--patch-4
+ steve@eicq.org--2005/eicq--main--0.8--patch-5
+ steve@eicq.org--2005/eicq--main--0.8--patch-6
+ steve@eicq.org--2005/eicq--main--0.8--patch-7
+ steve@eicq.org--2005/eicq--main--0.8--patch-8
+ steve@eicq.org--2005/eicq--main--0.8--patch-9
+ steve@eicq.org--2005/eicq--main--0.8--patch-10
+ steve@eicq.org--2005/eicq--main--0.8--patch-11
+ steve@eicq.org--2005/eicq--main--0.8--patch-12
+ steve@eicq.org--2005/eicq--main--0.8--patch-13
+ steve@eicq.org--2005/eicq--main--0.8--patch-14
+ steve@eicq.org--2005/eicq--main--0.8--patch-15
+ steve@eicq.org--2005/eicq--main--0.8--patch-16
+ steve@eicq.org--2005/eicq--main--0.8--patch-17
+ steve@eicq.org--2005/eicq--main--0.8--patch-18
+ steve@eicq.org--2005/eicq--main--0.8--patch-19
+ steve@eicq.org--2005/eicq--main--0.8--patch-20
+ steve@eicq.org--2005/eicq--main--0.8--patch-21
+ steve@eicq.org--2005/eicq--main--0.8--patch-22
+ steve@eicq.org--2005/eicq--main--0.8--patch-23
+ steve@eicq.org--2005/eicq--main--0.8--version-0
+ steve@eicq.org--2005/eicq--main--0.8--versionfix-1
+ steve@eicq.org--2006/eicq--main--0.9--base-0
+ steve@eicq.org--2006/eicq--main--0.9--patch-1
+ steve@eicq.org--2006/eicq--main--0.9--patch-2
+ steve@eicq.org--2006/eicq--main--0.9--patch-3
+ steve@eicq.org--2006/eicq--main--0.9--patch-4
+ steve@eicq.org--2006/eicq--main--0.9--patch-5
+ steve@eicq.org--2006/eicq--main--0.9--patch-6
+ steve@eicq.org--2006/eicq--main--0.9--patch-7
+ steve@eicq.org--2006/eicq--main--0.9--patch-8
+ steve@eicq.org--2006/eicq--main--0.9--patch-9
+ steve@eicq.org--2006/eicq--main--0.9--patch-10
+ steve@eicq.org--2006/eicq--main--0.9--patch-11
+ steve@eicq.org--2006/eicq--main--0.9--patch-12
+ steve@eicq.org--2006/eicq--main--0.9--patch-13
+ steve@eicq.org--2006/eicq--main--0.9--patch-14
+ steve@eicq.org--2006/eicq--main--0.9--patch-15
+
+
--- /dev/null
+# do not edit -- automatically generated by arch changelog
+# non-id: automatic-ChangeLog--steve@emchat.org--2007/emchat--main--0.9.2
+#
+
+2008-03-25 14:06:52 GMT Steve Youngs <steve@emchat.org> patch-20
+
+ Summary:
+ Unsuccessful attempt to implement adding users to SSI
+ Revision:
+ emchat--main--0.9.2--patch-20
+
+ This changeset tries to implement adding new users to your server side
+ contact lists. The bad news is that it isn't working. I'm committing so
+ that a) my work doesn't get lost, and b) so others can look at it and
+ possibly help me fix it.
+
+ * emchat.el (emchat-add-user-ssi): New.
+ (emchat-do-search-found-last): Update for new add-user stuff
+ (emchat-login): Add a `new-user' message type
+ (emchat-add-user): New.
+
+ * emchat-v8.el (emchat-v8-snac-srv-ssi-mod-ack): Update return codes.
+ (emchat-v8-snac-cli-ssi-add): Rewrite. But still not working yet
+ unfortunately.
+
+ * emchat-world.el (emchat-world-ssi-grp): New.
+ (emchat-world-next-ssi-id): New.
+ (emchat-world-add-new-user): New.
+
+
+ modified files:
+ emchat-v8.el emchat-world.el emchat.el
+
+
+2008-02-20 03:29:22 GMT Steve Youngs <steve@emchat.org> patch-19
+
+ Summary:
+ Fix emphasis face definitions
+ Revision:
+ emchat--main--0.9.2--patch-19
+
+ This changeset defines the faces used in emchat-emphasis in a different
+ way. Instead of using #'defface, they are now created with #'make-face.
+ They inherit from parent faces via #'set-face-parent and special
+ properties from #'set-face-property.
+
+ The old defface'd faces are now defcustom's (:type 'face) with the
+ default value set to the face from the #'make-face call.
+
+ This ixes a problem I was seeing when the default font isn't used for
+ other faces like italic and you don't get any emphasis happening in your
+ log buffer.
+
+ * emchat-emphasis.el (emchat-emphasis-bold): Migrate from defface to
+ defcustom plus the appropriate #'make-face and #'set-face-foo calls
+ (emchat-emphasis-italic): Ditto.
+ (emchat-emphasis-underline): Ditto.
+ (emchat-emphasis-underline-bold): Ditto.
+ (emchat-emphasis-underline-italic): Ditto.
+ (emchat-emphasis-bold-italic): Ditto.
+ (emchat-emphasis-underline-bold-italic): Ditto.
+ (emchat-emphasis-strikethru): Ditto.
+
+
+ modified files:
+ emchat-emphasis.el
+
+
+2008-02-10 07:21:54 GMT Steve Youngs <steve@emchat.org> patch-18
+
+ Summary:
+ Add a 48x48 png to use as frame icon
+ Revision:
+ emchat--main--0.9.2--patch-18
+
+ * images/emchat-icon.png: New.
+
+ new files:
+ images/.arch-ids/emchat-icon.png.id images/emchat-icon.png
+
+
+2007-12-27 17:27:49 GMT Steve Youngs <steve@emchat.org> patch-17
+
+ Summary:
+ Integrate EMchat world with SSI more closely
+ Revision:
+ emchat--main--0.9.2--patch-17
+
+ This changeset brings us a few steps closer to dealing with SSI
+ properly. We can now build up the world file almost entirely from SSI.
+ Your own UIN/Alias must exist in world for it to work. And obviously,
+ SSI has absolutely no idea about EMchat "groups".
+
+ Each entry in world now has SSI group and entry ID fields. These are
+ automatically added/maintained so no user intervention is required. We
+ need these ID numbers to add/del/modify SSI entries.
+
+ Also, #'emchat-add-user has been disabled. It is not yet working.
+
+ * emchat-v8.el (emchat-v8-get-ssi-mod-time): Removed. Moved to
+ emchat-world.el.
+ (emchat-v8-ssi-count): New. Temp storage for SSI entry count.
+ (emchat-v8-snac-srv-ssi-reply): Use it.
+ Also, update the local `world' from SSI.
+ (emchat-v8-snac-srv-ssi-up-to-date): Tell the user we're up to date.
+ (emchat-v8-snac-srv-replyinfo): Add missing FLAGS arg.
+ (emchat-v8-snac-cli-ssi-checkout): Fix.
+ (emchat-v8-pack-time): Now takes a cons cell of high/low ints as arg,
+ just like any other emacs time/date function.
+
+ * emchat.el (emchat-check-contact-list): New. Checks to see if the local
+ world is up to date.
+ (emchat-do-login-confirm): Use it.
+
+ * emchat-world.el (emchat-world-ssi-LastUpdateTime-regexp): New. Regexp
+ matching the LastUpdateTime in world.
+ (emchat-world-ssi-count-regexp): New. Regexp matching the entries
+ count in world.
+ (emchat-world-ssi-id-regexp): New. Regexp matching the SSI group and
+ entry ID's in world.
+ (emchat-world-rc-regexp): Improve the regexp.
+ (emchat-world-ssi-mod-time): New. Return, as a cons of high/low ints
+ the LastUpdateTime in world.
+ (emchat-world-ssi-count): New. Return the entries count in world.
+ (emchat-world-update-world-count): New. Update LastUpdateTime and
+ entries count in world from SSI.
+ (emchat-world-sync-ssi-maybe): New. Add contacts that exist in SSI but
+ not in world to world, and update/add SSI group ID info where/when
+ necessary.
+ (emchat-add-user): Disable. Not working, I'll reenable it when it's
+ fixed.
+ (emchat-world-update): Add a dirty horrible ugly hack to get around my
+ total lack of ability to write a decent regular expression. Or, to put
+ it another way... cope with SSI data in world.
+ (emchat-add-new-user-to-buddy-buffer): Whitespace touch-up in the
+ balloon-help transient. And don't try to add to SSI unless the new
+ contact is being added by the user.
+
+
+ modified files:
+ emchat-v8.el emchat-world.el emchat.el
+
+
+2007-12-22 07:45:59 GMT Steve Youngs <steve@emchat.org> patch-16
+
+ Summary:
+ SNAC #x13/#x06 almost complete!
+ Revision:
+ emchat--main--0.9.2--patch-16
+
+ This changeset gives us a working SNAC #x13/#x06 (roster reply) handler.
+ We are now getting all of the data, we're just not doing anything with it
+ apart from fill up your debug buffer.
+
+ Also, all incoming SNAC handling functions now take up to 3 args. We can
+ now do something with the SNAC flags.
+
+ BTW, this changeset would not be possible without the tremendous help I
+ got from Sebastian Freundt. Thanks VERY much, Sebastian for your SNAC
+ decoding skills. :-)
+
+ * emchat-v8.el (emchat-v8-snac-flags): New. Replaces the flags0 and
+ flags1 functions.
+ (emchat-v8-snac-rid): Renamed from `emchat-v8-snacrid'.
+ (emchat-v8-snac-srv-*): Add optional FLAGS arg.
+ (emchat-v8-snac-srv-ssi-reply): Rewritten. It is now working, we just
+ don't do anything with the results yet. But it's a good log
+ filler. :-)
+ (emchat-v8-handle-flap): Call the SNAC functions with 3 args, the extra
+ one being the SNAC flags.
+ (emchat-v8-fetch-time): Fix. Make it return something we can parse
+ with #'format-time-string and friends.
+ (emchat-v8-fetch-snac): Combine flags0 and flags1 into a single flags
+ element.
+ (emchat-v8-pack-snac): Ditto.
+ (emchat-v8-fetch-n-tlvs): New. For fetching a specific number of
+ TLV's.
+
+
+ modified files:
+ emchat-v8.el
+
+
+2007-12-21 00:45:05 GMT Steve Youngs <steve@emchat.org> patch-15
+
+ Summary:
+ Merged from hrop (patch 4) -- optimisations
+ Revision:
+ emchat--main--0.9.2--patch-15
+
+ Patches applied:
+
+ * hroptatyr@emchat.org--emchat/emchat--hrop--0.9.2--patch-4
+ minor, optimise packet reading using ENT if available
+
+ modified files:
+ emchat-v8.el
+
+ new patches:
+ hroptatyr@emchat.org--emchat/emchat--hrop--0.9.2--patch-4
+
+
+2007-12-20 15:45:06 GMT Steve Youngs <steve@emchat.org> patch-14
+
+ Summary:
+ Minor fixes to auth code
+ Revision:
+ emchat--main--0.9.2--patch-14
+
+ This changeset has some minor fixes to the authorisation code. It now
+ uses the family #x13 SSI packets. Plus a couple of other tiny tweaks not
+ worth mentioning.
+
+ * emchat.el (emchat-remove-yourself-from-buddy): I had my logic backwards
+ for the completion.
+ (emchat-authorize): Fix for SSI
+ (emchat-auth-request): Send this via family #x13 SSI
+ (emchat-auth-accept-reason): New. Self-explanatory
+
+ * emchat-v8.el (emchat-v8-snac-srv-ssi-reply): Comment out the guts and
+ just save the data to a variable. This is _ONLY_ for testing/debugging
+ purposes, untill I get this thing figured out.
+
+ * emchat-v8.el (emchat-v8-snac-cli-ssi-add): Use the new bstr packer.
+
+ * emchat-world.el (emchat-add-new-user-to-buddy-buffer): This is not yet
+ working. The change here was simply: don't try to add someone who is
+ already on your list. Which takes care of a TODO from lg. :-)
+
+
+ modified files:
+ emchat-v8.el emchat-world.el emchat.el
+
+
+2007-12-18 07:12:50 GMT Steve Youngs <steve@emchat.org> patch-13
+
+ Summary:
+ Fix a couple of byte-compiler warnings that crept in
+ Revision:
+ emchat--main--0.9.2--patch-13
+
+ * build.el (needed): Add `font'.
+ Autoload a macro from emchat-emphasis when compiling
+ custom-defines.el.
+
+ * emchat-emphasis.el (emchat-emphasis-alist): Use #'func notation in the
+ :set and :get keyword functions
+
+
+ modified files:
+ build.el emchat-emphasis.el
+
+
+2007-12-18 06:35:42 GMT Steve Youngs <steve@emchat.org> patch-12
+
+ Summary:
+ Fix contact list error during login
+ Revision:
+ emchat--main--0.9.2--patch-12
+
+ This changeset takes care of the last contact list related login bug.
+ Local-only contact lists are not supported anymore, so don't attempt to
+ send one to the server.
+
+ * emchat-v8.el (emchat-v8-snac-srv-reply-bos): Don't try to send the
+ contact list. It is all server-side lists now.
+
+
+ modified files:
+ emchat-v8.el
+
+
+2007-12-17 14:39:52 GMT Steve Youngs <steve@emchat.org> patch-11
+
+ Summary:
+ Fix last fix
+ Revision:
+ emchat--main--0.9.2--patch-11
+
+ * emchat.el (emchat-remove-yourself-from-buddy): Add missing arg to a
+ #'emchat-numeric-uin call.
+
+
+ modified files:
+ emchat.el
+
+
+2007-12-17 14:36:17 GMT Steve Youngs <steve@emchat.org> patch-10
+
+ Summary:
+ Add completion to #'emchat-remove-yourself-from-buddy
+ Revision:
+ emchat--main--0.9.2--patch-10
+
+ This changeset adds completion of UIN's when you are removing yourself
+ from somebody else's contact list. It will complete only the UIN's that
+ aren't in _your_ contact list unless you are tracking adds from everyone
+ regardless of them being on your list or not.
+
+ Also, the list of adds for the current session is pre-loaded from the
+ saved adds in ~/.emchat/recent-adds.
+
+ Once you have removed yourself from a person's contact list, both the
+ session list of adds and the on-disc list of adds are updated. The UIN
+ in question is removed.
+
+ * emchat.el (emchat-remove-yourself-from-buddy): Add completion.
+ Also pre-set `emchat-world-recently-added-by' from the save file on
+ disc.
+
+
+ modified files:
+ emchat.el
+
+
+2007-12-17 12:50:20 GMT Steve Youngs <steve@emchat.org> patch-9
+
+ Summary:
+ Make foreign add tracking a little more customisable
+ Revision:
+ emchat--main--0.9.2--patch-9
+
+ This changeset lets you choose if you'll track the UIN's of people adding
+ you to their contact list if they aren't on your list (default), or just
+ track every add regardless if they are on your list or not.
+
+ * emchat.el (emchat-do-added-you): Only keep track of people who add you
+ to your contact list if they are not already in _your_ contact list,
+ unless you set `emchat-world-track-all-adds'.
+
+ * emchat-world.el (emchat-world-track-all-adds): New. When non-nil, keep
+ track of _all_ people adding you to their contact list. Otherwise just
+ track people who aren't on _your_ list.
+
+
+ modified files:
+ emchat-world.el emchat.el
+
+
+2007-12-17 12:02:34 GMT Steve Youngs <steve@emchat.org> patch-8
+
+ Summary:
+ Fix/improve keeping track of people who add you to their list
+ Revision:
+ emchat--main--0.9.2--patch-8
+
+ * emchat.el (emchat-do-added-you): Fix a silly bug where an #'insert was
+ given a symbol instead of a string as an arg.
+ Also, ensure that a UIN is only added once to the list of
+ recent-added-bys.
+
+
+ modified files:
+ emchat.el
+
+
+2007-12-17 00:34:24 GMT Steve Youngs <steve@emchat.org> patch-7
+
+ Summary:
+ Keep track of people adding you to their contact lists
+ Revision:
+ emchat--main--0.9.2--patch-7
+
+ This changeset lets you keep track of anyone who adds you to their
+ contact list. For the current session, the info is a list
+ `emchat-world-recently-added-by'. For keeping track more permanently, it
+ is also saved to a file `emchat-recently-added-by-filename'.
+
+ * emchat-world.el (emchat-recently-added-by-filename): New. Keeps track
+ of people who add you to their list.
+ (emchat-world-recently-added-by): New. Same as above, but a variable
+ for this info in the current session.
+
+ * emchat.el (emchat-do-added-you): Keep track of people adding you to
+ their contact lists.
+
+
+ modified files:
+ emchat-world.el emchat.el
+
+
+2007-12-17 00:12:26 GMT Steve Youngs <steve@emchat.org> patch-6
+
+ Summary:
+ Typo fix
+ Revision:
+ emchat--main--0.9.2--patch-6
+
+ * emchat.el (emchat-remove-yourself-from-buddy): Typo in docstring.
+
+
+ modified files:
+ emchat.el
+
+
+2007-12-17 00:02:54 GMT Steve Youngs <steve@emchat.org> patch-5
+
+ Summary:
+ More SSI fixes/additions
+ Revision:
+ emchat--main--0.9.2--patch-5
+
+ This changeset has more SSI (Server Side Info) fixes and additions.
+ We're still not completely there yet, but getting closer.
+
+ There is one new user command:
+
+ #'emchat-remove-yourself-from-buddy
+
+ * emchat.el (emchat-remove-yourself-from-buddy): New. Use this to remove
+ yourself from _somebody else's_ contact list.
+
+ * emchat-v8.el (emchat-v8-snac-list): Mostly whitespace changes, plus the
+ currently broken family #x13 packets have been noted.
+ The rest of the #x13 packet functions have been added, but not all are
+ working yet. The ones that aren't are marked.
+
+ modified files:
+ emchat-v8.el emchat.el
+
+
+2007-12-14 23:59:57 GMT Steve Youngs <steve@emchat.org> patch-4
+
+ Summary:
+ Begin implementing SSI (server-side contact lists)
+ Revision:
+ emchat--main--0.9.2--patch-4
+
+ This changeset begins EMchat's migration to using SSI. SSI is Server
+ Side Info. We have to do this because AOL has dropped support for the
+ old Mirabilis ICQ protocol and now ICQ is totally OSCAR protocol. One of
+ the "features", and I use that term loosely, of OSCAR is that it doesn't
+ support local contact lists.
+
+ As yet, EMchat can't add/modify server-side contact lists. Until we get
+ that working, you can use a client that does, I used ICQ2go, to add all
+ your contacts to the server list. Then you can switch back to EMchat and
+ things will work. You'll see status updates etc.
+
+ Another thing this changeset does is to convert all of emchat-v8.el to
+ using hex everywhere. It used to be hex in some places and dec in
+ others. This keeps it all consistant. C-x C-f emchat-v8.el and think in
+ hex! :-)
+
+ Beware, this is nowhere near a complete implementation. I simply used a
+ fooking big hammer to get it usable. More changesets will follow that
+ will iron out the bugs.
+
+ * emchat.el (emchat-do-login-confirm): Use `emchat-activate-contact-list'
+ instead of `emchat-send-contact-list'.
+ (emchat-activate-contact-list): New. It tells the server that we want
+ to use server-side contact lists.
+
+ * emchat-v8.el (emchat-v8-snacv-list): Convert to hex and tidy it up.
+ (emchat-v8-snac-list): Convert all to hex, add function items for all
+ the SSI packets. Not all these functions have been written yet, but at
+ least now when an as yet unimplemented packet comes in, you'll get a
+ name to the func def void error. :-)
+ (emchat-v8-snac-srv-ssi-reply): New. Currently no-op. This is the
+ packet the server sends when we ask for the server-side contact list to
+ be transferred.
+ (emchat-v8-snac-srv-ssi-rights-reply): New. The packet the server
+ sends when we request rights/limits info for SSI. Currently we don't
+ do anything with this, but it is logged to the emchat-debug buffer.
+ (emchat-v8-snac-srv-rates): Use hex.
+ (emchat-v8-snac-srv-pause): Use hex.
+ (emchat-v8-snac-cli-ssi-add): New. Add a contact to server-side contact
+ list. BROKEN.
+ (emchat-v8-snac-cli-ssi-edit-end): New. Send this packet to signal the
+ end of modifying SSI lists.
+ (emchat-v8-snac-cli-ssi-edit-begin): New. Send this packet to begin
+ modifying SSI lists.
+ (emchat-v8-snac-cli-ssi-activate): New. Tells the server that you want
+ to use SSI contact lists.
+ (emchat-v8-snac-cli-ssi-right-request): New. Request rate/limit info
+ for SSI.
+ (emchat-v8-snac-cli-ssi-request): New. Request that the server-side
+ contact list be sent to you.
+ (emchat-v8-snac-cli-setstatus): Use hex.
+ (emchat-v8-snac-cli-add-contact): Use hex.
+ (emchat-v8-snac-cli-addvisible): Use hex.
+ (emchat-v8-snac-cli-remvisible): Use hex.
+ (emchat-v8-snac-cli-addinvisible): Use hex.
+ (emchat-v8-snac-cli-reminvisible): Use hex.
+ (emchat-v8-pack-meta-snac): Use hex.
+ (emchat-v8-snac-cli-ready): Use hex.
+ (emchat-v8-snac-cli-families): Use hex.
+ (emchat-v8-snac-cli-ratesrequest): Use hex.
+ (emchat-v8-snac-cli-reqinfo): Use hex.
+ (emchat-v8-snac-cli-reqlocation): Use hex.
+ (emchat-v8-snac-cli-reqbuddy): Use hex.
+ (emchat-v8-snac-cli-reqicbm): Use hex.
+ (emchat-v8-snac-cli-sendmsg): Use hex.
+ (emchat-v8-snac-cli-reqbos): Use hex.
+
+
+ modified files:
+ emchat-v8.el emchat.el
+
+
+2007-11-20 04:13:43 GMT Steve Youngs <steve@emchat.org> patch-3
+
+ Summary:
+ Add logos and externalise toolbar glyphs
+ Revision:
+ emchat--main--0.9.2--patch-3
+
+ This changeset adds our logo to the top of the log buffer. It also adds
+ a button to the default-toolbar, and takes all the "inline" xpm's out of
+ emchat-toolbar.el.
+
+ * Makefile (DATA_DIR): New. Where the logos and icons go.
+ (DATA_FILES): New. The logos and icons.
+ (install): Install the $DATA_FILES
+
+ * emchat-utils.el (emchat-glyph-dir): New. So EMchat can find
+ logo/icon files.
+
+ * emchat-toolbar.el (emchat-password-icon): Data exported to external
+ file.
+ (emchat-send-message-here-icon): Ditto.
+ (emchat-send-message-around-icon): Ditto.
+ (emchat-send-url-here-icon): Ditto.
+ (emchat-send-url-around-icon): Ditto.
+ (emchat-query-info-here-icon): Ditto.
+ (emchat-query-info-around-icon): Ditto.
+ (emchat-update-info-icon): Ditto.
+ (emchat-search-icon): Ditto.
+ (emchat-authorize-here-icon): Ditto.
+ (emchat-login-icon): Ditto.
+ (emchat-logout-icon): Ditto.
+ (emchat-exit-icon): Ditto.
+ (emchat-new-log-icon): Ditto.
+ (emchat-help-icon): Ditto.
+
+ * emchat-log.el (emchat-log-logo): Sexy logo for the top of the log.
+ (emchat-log-header): The old log intro as an xbm. Done this way so we
+ can align it nicely with the logo.
+ (emchat-log-show-buffer): Use them.
+
+ * emchat.el (emchat-toolbar-login): Command run from default-toolbar.
+ (emchat-toolbar-icon): Icon for default-toolbar.
+ (emchat-toolbar-spec): Button spec for default-toolbar.
+ (emchat-add-to-toolbar): Adds our button to default-toolbar.
+
+
+ new files:
+ images/.arch-ids/=id images/.arch-ids/auth-here.xpm.id
+ images/.arch-ids/exit.xpm.id images/.arch-ids/help.xpm.id
+ images/.arch-ids/info-around.xpm.id
+ images/.arch-ids/info-here.xpm.id
+ images/.arch-ids/log-header.xbm.id
+ images/.arch-ids/login.xpm.id images/.arch-ids/logo.png.id
+ images/.arch-ids/logout.xpm.id
+ images/.arch-ids/mini-logo.png.id
+ images/.arch-ids/msg-around.xpm.id
+ images/.arch-ids/msg-here.xpm.id
+ images/.arch-ids/new-log.xpm.id
+ images/.arch-ids/password.xpm.id
+ images/.arch-ids/search.xpm.id
+ images/.arch-ids/upd-info.xpm.id
+ images/.arch-ids/url-around.xpm.id
+ images/.arch-ids/url-here.xpm.id images/auth-here.xpm
+ images/exit.xpm images/help.xpm images/info-around.xpm
+ images/info-here.xpm images/log-header.xbm images/login.xpm
+ images/logo.png images/logout.xpm images/mini-logo.png
+ images/msg-around.xpm images/msg-here.xpm images/new-log.xpm
+ images/password.xpm images/search.xpm images/upd-info.xpm
+ images/url-around.xpm images/url-here.xpm
+
+ modified files:
+ Makefile emchat-log.el emchat-toolbar.el emchat-utils.el
+ emchat.el
+
+ new directories:
+ images images/.arch-ids
+
+
+2007-11-16 16:50:33 GMT Steve Youngs <steve@emchat.org> patch-2
+
+ Summary:
+ Update the donation glyphs/code
+ Revision:
+ emchat--main--0.9.2--patch-2
+
+ * emchat.el (emchat-make-donation): Update donation URL.
+ (emchat-paypal-glyph): Use newer, sexier glyph.
+ (emchat-maybe-later-glyph): Ditto.
+
+
+ modified files:
+ emchat.el
+
+
+2007-11-15 01:49:45 GMT Steve Youngs <steve@emchat.org> patch-1
+
+ Summary:
+ The Great Eicq -> EMchat Renaming
+ Revision:
+ emchat--main--0.9.2--patch-1
+
+ Waaaaay too much stuff to log each and every change. But it was all
+ simply renaming from Eicq to EMchat and eicq to emchat.
+
+ new files:
+ ChangeLog.d/.arch-ids/ChangeLog-0.9.1.Eicq.id
+ ChangeLog.d/ChangeLog-0.9.1.Eicq
+
+ modified files:
+ .arch-inventory INSTALL Makefile NEWS README TODO build.el
+ emchat-buddy.el emchat-convert.el emchat-curl.el
+ emchat-doctor.el emchat-emphasis.el emchat-history.el
+ emchat-log.el emchat-menu.el emchat-meta.el emchat-report.el
+ emchat-setup.el emchat-status.el emchat-toolbar.el
+ emchat-track.el emchat-utils.el emchat-v8.el emchat-wharf.el
+ emchat-world.el emchat-xwem.el emchat.el emchat.texi
+
+ renamed files:
+ .arch-ids/eicq-buddy.el.id
+ ==> .arch-ids/emchat-buddy.el.id
+ .arch-ids/eicq-convert.el.id
+ ==> .arch-ids/emchat-convert.el.id
+ .arch-ids/eicq-curl.el.id
+ ==> .arch-ids/emchat-curl.el.id
+ .arch-ids/eicq-doctor.el.id
+ ==> .arch-ids/emchat-doctor.el.id
+ .arch-ids/eicq-emphasis.el.id
+ ==> .arch-ids/emchat-emphasis.el.id
+ .arch-ids/eicq-history.el.id
+ ==> .arch-ids/emchat-history.el.id
+ .arch-ids/eicq-log.el.id
+ ==> .arch-ids/emchat-log.el.id
+ .arch-ids/eicq-menu.el.id
+ ==> .arch-ids/emchat-menu.el.id
+ .arch-ids/eicq-meta.el.id
+ ==> .arch-ids/emchat-meta.el.id
+ .arch-ids/eicq-report.el.id
+ ==> .arch-ids/emchat-report.el.id
+ .arch-ids/eicq-setup.el.id
+ ==> .arch-ids/emchat-setup.el.id
+ .arch-ids/eicq-status.el.id
+ ==> .arch-ids/emchat-status.el.id
+ .arch-ids/eicq-toolbar.el.id
+ ==> .arch-ids/emchat-toolbar.el.id
+ .arch-ids/eicq-track.el.id
+ ==> .arch-ids/emchat-track.el.id
+ .arch-ids/eicq-utils.el.id
+ ==> .arch-ids/emchat-utils.el.id
+ .arch-ids/eicq-v8.el.id
+ ==> .arch-ids/emchat-v8.el.id
+ .arch-ids/eicq-wharf.el.id
+ ==> .arch-ids/emchat-wharf.el.id
+ .arch-ids/eicq-world.el.id
+ ==> .arch-ids/emchat-world.el.id
+ .arch-ids/eicq-xwem.el.id
+ ==> .arch-ids/emchat-xwem.el.id
+ .arch-ids/eicq.el.id
+ ==> .arch-ids/emchat.el.id
+ .arch-ids/eicq.texi.id
+ ==> .arch-ids/emchat.texi.id
+ ChangeLog.d/.arch-ids/ChangeLog-0.6.id
+ ==> ChangeLog.d/.arch-ids/ChangeLog-0.6.Eicq.id
+ ChangeLog.d/.arch-ids/ChangeLog-0.7.id
+ ==> ChangeLog.d/.arch-ids/ChangeLog-0.7.Eicq.id
+ ChangeLog.d/.arch-ids/ChangeLog-0.8.id
+ ==> ChangeLog.d/.arch-ids/ChangeLog-0.8.Eicq.id
+ ChangeLog.d/.arch-ids/ChangeLog-0.9.id
+ ==> ChangeLog.d/.arch-ids/ChangeLog-0.9.Eicq.id
+ ChangeLog.d/ChangeLog-0.6
+ ==> ChangeLog.d/ChangeLog-0.6.Eicq
+ ChangeLog.d/ChangeLog-0.7
+ ==> ChangeLog.d/ChangeLog-0.7.Eicq
+ ChangeLog.d/ChangeLog-0.8
+ ==> ChangeLog.d/ChangeLog-0.8.Eicq
+ ChangeLog.d/ChangeLog-0.9
+ ==> ChangeLog.d/ChangeLog-0.9.Eicq
+ eicq-buddy.el
+ ==> emchat-buddy.el
+ eicq-convert.el
+ ==> emchat-convert.el
+ eicq-curl.el
+ ==> emchat-curl.el
+ eicq-doctor.el
+ ==> emchat-doctor.el
+ eicq-emphasis.el
+ ==> emchat-emphasis.el
+ eicq-history.el
+ ==> emchat-history.el
+ eicq-log.el
+ ==> emchat-log.el
+ eicq-menu.el
+ ==> emchat-menu.el
+ eicq-meta.el
+ ==> emchat-meta.el
+ eicq-report.el
+ ==> emchat-report.el
+ eicq-setup.el
+ ==> emchat-setup.el
+ eicq-status.el
+ ==> emchat-status.el
+ eicq-toolbar.el
+ ==> emchat-toolbar.el
+ eicq-track.el
+ ==> emchat-track.el
+ eicq-utils.el
+ ==> emchat-utils.el
+ eicq-v8.el
+ ==> emchat-v8.el
+ eicq-wharf.el
+ ==> emchat-wharf.el
+ eicq-world.el
+ ==> emchat-world.el
+ eicq-xwem.el
+ ==> emchat-xwem.el
+ eicq.el
+ ==> emchat.el
+ eicq.texi
+ ==> emchat.texi
+
+
+2007-11-13 05:34:39 GMT Steve Youngs <steve@eicq.org> base-0
+
+ Summary:
+ tag of steve@eicq.org--2007/eicq--main--0.9.1--version-0
+ Revision:
+ emchat--main--0.9.2--base-0
+
+ (automatically generated log message)
+
+ new patches:
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-1
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-2
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-3
+ hroptatyr@eicq.org--eicq/eicq--hrop--0.9.1--patch-4
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-1
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-2
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-4
+ lg@xwem.org--2005/eicq--lg--0.7--patch-1
+ lg@xwem.org--2005/eicq--lg--0.7--patch-2
+ lg@xwem.org--2005/eicq--lg--0.7--patch-5
+ lg@xwem.org--2005/eicq--lg--0.7--patch-8
+ lg@xwem.org--2005/eicq--lg--0.7--patch-9
+ lg@xwem.org--2005/eicq--lg--0.7--patch-12
+ lg@xwem.org--2005/eicq--lg--0.7--patch-13
+ lg@xwem.org--2005/eicq--lg--0.7--patch-14
+ lg@xwem.org--2005/eicq--lg--0.7--patch-16
+ lg@xwem.org--2005/eicq--lg--0.7--patch-18
+ lg@xwem.org--2005/eicq--lg--0.7--patch-19
+ lg@xwem.org--2005/eicq--lg--0.7--patch-20
+ lg@xwem.org--2005/eicq--lg--0.7--patch-21
+ lg@xwem.org--2005/eicq--lg--0.7--patch-23
+ lg@xwem.org--2005/eicq--lg--0.7--patch-28
+ lg@xwem.org--2005/eicq--lg--0.8--patch-1
+ lg@xwem.org--2005/eicq--lg--0.8--patch-2
+ lg@xwem.org--2005/eicq--lg--0.8--patch-3
+ lg@xwem.org--2005/eicq--lg--0.8--patch-4
+ lg@xwem.org--2007/eicq--lg--0.9--patch-1
+ lg@xwem.org--2007/eicq--lg--0.9--patch-2
+ lg@xwem.org--2007/eicq--lg--0.9--patch-3
+ lg@xwem.org--2007/eicq--lg--0.9--patch-4
+ lg@xwem.org--2007/eicq--lg--0.9--patch-5
+ lg@xwem.org--2007/eicq--lg--0.9--patch-9
+ steve@eicq.org--2004/eicq--main--0.6--base-0
+ steve@eicq.org--2004/eicq--main--0.6--patch-1
+ steve@eicq.org--2004/eicq--main--0.6--patch-2
+ steve@eicq.org--2004/eicq--main--0.6--patch-3
+ steve@eicq.org--2004/eicq--main--0.6--patch-4
+ steve@eicq.org--2004/eicq--main--0.6--patch-5
+ steve@eicq.org--2004/eicq--main--0.6--patch-6
+ steve@eicq.org--2004/eicq--main--0.6--patch-7
+ steve@eicq.org--2004/eicq--main--0.6--patch-8
+ steve@eicq.org--2004/eicq--main--0.6--patch-9
+ steve@eicq.org--2004/eicq--main--0.6--patch-10
+ steve@eicq.org--2004/eicq--main--0.6--patch-11
+ steve@eicq.org--2004/eicq--main--0.6--patch-12
+ steve@eicq.org--2004/eicq--main--0.6--patch-13
+ steve@eicq.org--2004/eicq--main--0.6--patch-14
+ steve@eicq.org--2004/eicq--main--0.6--patch-15
+ steve@eicq.org--2005/eicq--main--0.7--base-0
+ steve@eicq.org--2005/eicq--main--0.7--patch-1
+ steve@eicq.org--2005/eicq--main--0.7--patch-2
+ steve@eicq.org--2005/eicq--main--0.7--patch-3
+ steve@eicq.org--2005/eicq--main--0.7--patch-4
+ steve@eicq.org--2005/eicq--main--0.7--patch-5
+ steve@eicq.org--2005/eicq--main--0.7--patch-6
+ steve@eicq.org--2005/eicq--main--0.7--patch-7
+ steve@eicq.org--2005/eicq--main--0.7--patch-8
+ steve@eicq.org--2005/eicq--main--0.7--patch-9
+ steve@eicq.org--2005/eicq--main--0.7--patch-10
+ steve@eicq.org--2005/eicq--main--0.7--patch-11
+ steve@eicq.org--2005/eicq--main--0.7--patch-12
+ steve@eicq.org--2005/eicq--main--0.7--patch-13
+ steve@eicq.org--2005/eicq--main--0.7--patch-14
+ steve@eicq.org--2005/eicq--main--0.7--patch-15
+ steve@eicq.org--2005/eicq--main--0.7--patch-16
+ steve@eicq.org--2005/eicq--main--0.7--patch-17
+ steve@eicq.org--2005/eicq--main--0.7--patch-18
+ steve@eicq.org--2005/eicq--main--0.7--patch-19
+ steve@eicq.org--2005/eicq--main--0.7--patch-20
+ steve@eicq.org--2005/eicq--main--0.7--patch-21
+ steve@eicq.org--2005/eicq--main--0.7--patch-22
+ steve@eicq.org--2005/eicq--main--0.7--patch-23
+ steve@eicq.org--2005/eicq--main--0.7--patch-24
+ steve@eicq.org--2005/eicq--main--0.7--patch-25
+ steve@eicq.org--2005/eicq--main--0.7--patch-26
+ steve@eicq.org--2005/eicq--main--0.7--patch-27
+ steve@eicq.org--2005/eicq--main--0.7--patch-28
+ steve@eicq.org--2005/eicq--main--0.7--patch-29
+ steve@eicq.org--2005/eicq--main--0.7--patch-30
+ steve@eicq.org--2005/eicq--main--0.7--patch-31
+ steve@eicq.org--2005/eicq--main--0.7--patch-32
+ steve@eicq.org--2005/eicq--main--0.7--patch-33
+ steve@eicq.org--2005/eicq--main--0.7--patch-34
+ steve@eicq.org--2005/eicq--main--0.7--patch-35
+ steve@eicq.org--2005/eicq--main--0.7--patch-36
+ steve@eicq.org--2005/eicq--main--0.7--patch-37
+ steve@eicq.org--2005/eicq--main--0.7--patch-38
+ steve@eicq.org--2005/eicq--main--0.7--patch-39
+ steve@eicq.org--2005/eicq--main--0.7--patch-40
+ steve@eicq.org--2005/eicq--main--0.7--patch-41
+ steve@eicq.org--2005/eicq--main--0.7--patch-42
+ steve@eicq.org--2005/eicq--main--0.7--patch-43
+ steve@eicq.org--2005/eicq--main--0.7--patch-44
+ steve@eicq.org--2005/eicq--main--0.7--patch-45
+ steve@eicq.org--2005/eicq--main--0.7--patch-46
+ steve@eicq.org--2005/eicq--main--0.7--patch-47
+ steve@eicq.org--2005/eicq--main--0.7--patch-48
+ steve@eicq.org--2005/eicq--main--0.7--patch-49
+ steve@eicq.org--2005/eicq--main--0.7--patch-50
+ steve@eicq.org--2005/eicq--main--0.7--patch-51
+ steve@eicq.org--2005/eicq--main--0.7--patch-52
+ steve@eicq.org--2005/eicq--main--0.7--patch-53
+ steve@eicq.org--2005/eicq--main--0.7--patch-54
+ steve@eicq.org--2005/eicq--main--0.7--patch-55
+ steve@eicq.org--2005/eicq--main--0.7--patch-56
+ steve@eicq.org--2005/eicq--main--0.7--patch-57
+ steve@eicq.org--2005/eicq--main--0.7--patch-58
+ steve@eicq.org--2005/eicq--main--0.7--patch-59
+ steve@eicq.org--2005/eicq--main--0.7--patch-60
+ steve@eicq.org--2005/eicq--main--0.7--version-0
+ steve@eicq.org--2005/eicq--main--0.8--base-0
+ steve@eicq.org--2005/eicq--main--0.8--patch-1
+ steve@eicq.org--2005/eicq--main--0.8--patch-2
+ steve@eicq.org--2005/eicq--main--0.8--patch-3
+ steve@eicq.org--2005/eicq--main--0.8--patch-4
+ steve@eicq.org--2005/eicq--main--0.8--patch-5
+ steve@eicq.org--2005/eicq--main--0.8--patch-6
+ steve@eicq.org--2005/eicq--main--0.8--patch-7
+ steve@eicq.org--2005/eicq--main--0.8--patch-8
+ steve@eicq.org--2005/eicq--main--0.8--patch-9
+ steve@eicq.org--2005/eicq--main--0.8--patch-10
+ steve@eicq.org--2005/eicq--main--0.8--patch-11
+ steve@eicq.org--2005/eicq--main--0.8--patch-12
+ steve@eicq.org--2005/eicq--main--0.8--patch-13
+ steve@eicq.org--2005/eicq--main--0.8--patch-14
+ steve@eicq.org--2005/eicq--main--0.8--patch-15
+ steve@eicq.org--2005/eicq--main--0.8--patch-16
+ steve@eicq.org--2005/eicq--main--0.8--patch-17
+ steve@eicq.org--2005/eicq--main--0.8--patch-18
+ steve@eicq.org--2005/eicq--main--0.8--patch-19
+ steve@eicq.org--2005/eicq--main--0.8--patch-20
+ steve@eicq.org--2005/eicq--main--0.8--patch-21
+ steve@eicq.org--2005/eicq--main--0.8--patch-22
+ steve@eicq.org--2005/eicq--main--0.8--patch-23
+ steve@eicq.org--2005/eicq--main--0.8--version-0
+ steve@eicq.org--2005/eicq--main--0.8--versionfix-1
+ steve@eicq.org--2006/eicq--main--0.9--base-0
+ steve@eicq.org--2006/eicq--main--0.9--patch-1
+ steve@eicq.org--2006/eicq--main--0.9--patch-2
+ steve@eicq.org--2006/eicq--main--0.9--patch-3
+ steve@eicq.org--2006/eicq--main--0.9--patch-4
+ steve@eicq.org--2006/eicq--main--0.9--patch-5
+ steve@eicq.org--2006/eicq--main--0.9--patch-6
+ steve@eicq.org--2006/eicq--main--0.9--patch-7
+ steve@eicq.org--2006/eicq--main--0.9--patch-8
+ steve@eicq.org--2006/eicq--main--0.9--patch-9
+ steve@eicq.org--2006/eicq--main--0.9--patch-10
+ steve@eicq.org--2006/eicq--main--0.9--patch-11
+ steve@eicq.org--2006/eicq--main--0.9--patch-12
+ steve@eicq.org--2006/eicq--main--0.9--patch-13
+ steve@eicq.org--2006/eicq--main--0.9--patch-14
+ steve@eicq.org--2006/eicq--main--0.9--patch-15
+ steve@eicq.org--2007/eicq--main--0.9.1--base-0
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-1
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-2
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-3
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-4
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-5
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-6
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-7
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-8
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-9
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-10
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-11
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-12
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-13
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-14
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-15
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-16
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-17
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-18
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-19
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-20
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-21
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-22
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-23
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-24
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-25
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-26
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-27
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-28
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-29
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-30
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-31
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-32
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-33
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-34
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-35
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-36
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-37
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-38
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-39
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-40
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-41
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-42
+ steve@eicq.org--2007/eicq--main--0.9.1--patch-43
+ steve@eicq.org--2007/eicq--main--0.9.1--version-0
+
+
--- /dev/null
+# do not edit -- automatically generated by arch changelog
+# non-id: automatic-ChangeLog--steve@eicq.org--2006/eicq--main--0.9
+#
+
+2007-01-17 13:59:13 GMT Steve Youngs <steve@eicq.org> patch-15
+
+ Summary:
+ Merged from lg (patch 1) -- Mule fix.
+ Revision:
+ eicq--main--0.9--patch-15
+
+ Patches applied:
+
+ * lg@xwem.org--2007/eicq--lg--0.9--patch-1
+ Mule fix
+
+ modified files:
+ eicq.el
+
+ new patches:
+ lg@xwem.org--2007/eicq--lg--0.9--patch-1
+
+
+2007-01-15 17:20:16 GMT Steve Youngs <steve@eicq.org> patch-14
+
+ Summary:
+ Makefile tweaks.
+ Revision:
+ eicq--main--0.9--patch-14
+
+ This changeset brings Eicq's build inline with the new LFS compliant
+ SXEmacs install hierarchy/search paths.
+
+ * Makefile (PREFIX): Default to new SXEmacs LFS compliant directory.
+ (LISP_DIR): Move to _after_ PREFIX.
+ (INFO_DIR): Ditto.
+
+
+ modified files:
+ Makefile
+
+
+2006-10-09 00:56:50 GMT Steve Youngs <steve@eicq.org> patch-13
+
+ Summary:
+ Build improvements
+ Revision:
+ eicq--main--0.9--patch-13
+
+
+ * eicq.el: Byte-compiler warning fix... autoload
+ `eicq-wharf-dec-messages' at compile time.
+
+ * Makefile (XEMACS): Default to sxemacs
+ (PREFIX): Default to either
+ /usr/local/lib/sxemacs/site-packages
+ or
+ /usr/local/lib/xemacs/site-packages
+ depending on the value of $XEMACS.
+
+
+ modified files:
+ Makefile eicq.el
+
+
+2006-10-09 00:08:23 GMT Steve Youngs <steve@eicq.org> patch-12
+
+ Summary:
+ Saner, easier handling of fill-column in log buffer
+ Revision:
+ eicq--main--0.9--patch-12
+
+ The changeset takes care of an issue I'd been having with the fill-column
+ in the log buffer. If you ran Eicq in a separate frame the log buffer's
+ fill-column was always way too high. Originally the fill-column was
+ supposed to have been calculated based on the width of the frame. Now
+ what we do is leave fill-column alone unless the user has set
+ `eicq-log-fill-column'.
+
+ * eicq-log.el (eicq-log-mode): Don't try to be clever with the
+ fill-column, just leave it at the default setting unless the user
+ explicitly sets a different value.
+ (eicq-log-fill-column): Update doc string.
+
+
+ modified files:
+ eicq-log.el
+
+
+2006-09-14 06:16:47 GMT Steve Youngs <steve@eicq.org> patch-11
+
+ Summary:
+ Wharf show status, automatically decrement msg count.
+ Revision:
+ eicq--main--0.9--patch-11
+
+ This changeset enhances the EicqWharf. It will now automatically
+ decrement the message count when sending a message. And it also shows
+ your current status.
+
+ Another small change is that if you run Eicq in a separate frame by
+ setting `eicq-start-in-new-frame' to `t', the frame has the name property
+ set. This helps you do sexy things with it in WMs like Sawfish.
+
+ * eicq.el (eicq-show-window): Give the Eicq frame a name property
+ "EicqLog". This actually sets the Xwindow "class" for the frame, which
+ in turn, helps WMs identify it. Think: Sawfish matched-windows.
+ (eicq-send-message-alias-around): Decrement the message count in
+ EicqWharf if it is being used.
+ (eicq-send-url-alias-around): Ditto.
+
+ * eicq-wharf.el (eicq-wharf-new-frame): Insert the user's actual status
+ instead of the word "Status".
+
+ * eicq-wharf.el (eicq-wharf-update-status): New. Updates the status line
+ in the EicqWharf.
+
+ * eicq-status.el (eicq-change-status): Maybe update the status line in
+ the EicqWharf.
+
+
+
+
+ modified files:
+ eicq-status.el eicq-wharf.el eicq.el
+
+
+2006-09-01 22:22:10 GMT Steve Youngs <steve@eicq.org> patch-10
+
+ Summary:
+ Handle aliases with strange characters in them
+ Revision:
+ eicq--main--0.9--patch-10
+
+ * eicq.el (eicq-alias-around): Fix regexp to handle alias names with
+ non-word-class characters in them.
+
+
+ modified files:
+ eicq.el
+
+
+2006-08-19 16:27:42 GMT Steve Youngs <steve@eicq.org> patch-9
+
+ Summary:
+ Fix problem with sounds not working in SXEmacs
+ Revision:
+ eicq--main--0.9--patch-9
+
+ This actually points to a bigger problem in SXEmacs itself because
+ `play-media-stream' is an autoloaded function, but it isn't being
+ autoloaded.
+
+ * eicq.el: Load sound.el at compile-time.
+
+
+ modified files:
+ eicq.el
+
+
+2006-07-08 06:09:55 GMT Steve Youngs <steve@eicq.org> patch-8
+
+ Summary:
+ Fix incoming and outgoing authorisation requests
+ Revision:
+ eicq--main--0.9--patch-8
+
+ This changeset pretty much finishes the authorisation code in Eicq.
+ Incoming auth requests can be accepted or rejected. If you accept the
+ request, the user that sent it will be added to your contact list and
+ they are sent an `ADDEDYOU' message. If you reject the request, they are
+ sent a `auth-reject' message and reason... see:
+ `eicq-auth-reject-reason'.
+
+ Outgoing auth requests can also be sent to other users. Use
+ `eicq-auth-request' to do this, and see `eicq-auth-request-reason' for
+ the message that gets sent with the request.
+
+ I'd like to say something about ICQ authorisations. They are pretty much
+ a complete waste of time. They are only useful with crippled ICQ clients
+ that don't let you send messages to users who aren't on your contact
+ list and don't let you add users to your contact list without
+ authorisation. Eicq does _NOT_ fall into this category of ICQ client.
+
+ * eicq-v8.el (eicq-v8-snac-srv-authreply): New. Handle SRV_AUTHREPLY.
+
+ * eicq.el (eicq-auth-reject-reason): New. Message to send to a user when
+ rejecting their authorisation request.
+ (eicq-auth-request-reason): New. Message to send to a user when
+ requesting authorisation from them.
+ (eicq-do-auth-accept): New. Handle incoming accepted auth messages.
+ (eicq-do-auth-reject): New. Handle incoming rejected auth messages.
+ (eicq-do-message-helper): Display authorisation rejected reason.
+ (eicq-login): Add `auth-reject' and `auth-accept' message types.
+ (eicq-authorize): Fix. Accept or reject authorisation requests. If
+ accepted, the user is added to the contact list.
+ (eicq-auth-request): New. Request authorisation from another user.
+
+
+ modified files:
+ eicq-v8.el eicq.el
+
+
+2006-06-23 04:47:52 GMT Steve Youngs <steve@eicq.org> patch-7
+
+ Summary:
+ New macros to execute code only in either XEmacs or SXEmacs
+ Revision:
+ eicq--main--0.9--patch-7
+
+ The motivation for this was seeing an obsolete warning about
+ `play-sound-file' when building Eicq in SXEmacs. Two new macros,
+ `eicq-do-in-xemacs' and `eicq-do-in-sxemacs' can be used to wrap stuff
+ that can only be executed in either XEmacs or SXEmacs.
+
+ * eicq.el (eicq-do-in-xemacs): New. To execute code only in XEmacs.
+ (eicq-do-in-sxemacs): New. As above, except for SXEmacs.
+ (eicq-maybe-play-sound): Use them here so SXEmacs can call the media
+ defun's directly, thus avoiding byte-compiler warnings.
+ (play-media-stream): Autoload this.
+
+
+ modified files:
+ eicq.el
+
+
+2006-06-23 03:25:53 GMT Steve Youngs <steve@eicq.org> patch-6
+
+ Summary:
+ Fix sending messages when current msg contains "[text]" in it
+ Revision:
+ eicq--main--0.9--patch-6
+
+ If somebody sent you a message and it contained "[text]" in it, when you
+ hit `m' to reply, you'd get a "no alias/uin" error. This fixes that.
+
+ * eicq.el (eicq-alias-around): Fix regexp so that you don't get errors
+ when a message contains "[sometext]" in it.
+
+
+ modified files:
+ eicq.el
+
+
+2006-03-18 10:54:31 GMT Steve Youngs <steve@eicq.org> patch-5
+
+ Summary:
+ regexp-opt build fix
+ Revision:
+ eicq--main--0.9--patch-5
+
+ This fixes a build problem of not finding regexp-opt. I have no idea why
+ I wasn't seeing it in my WD, but there you go.
+
+ * eicq-buddy.el: Don't autoload regexp-opt here.
+
+ * eicq-report.el: Or here.
+
+ * eicq.el: Do it here instead.
+
+
+ modified files:
+ eicq-buddy.el eicq-report.el eicq.el
+
+
+2006-02-15 06:20:13 GMT Steve Youngs <steve@eicq.org> patch-4
+
+ Summary:
+ Tweak alias tab-completion a little
+ Revision:
+ eicq--main--0.9--patch-4
+
+ This changeset changes the completion on aliases a little. It used to
+ complete only on connected and/or active aliases. Now it completes on
+ _all_ aliases. I find that this makes more sense as I frequently send
+ messages to people who aren't online.
+
+ * eicq.el (eicq-completing-alias): Complete on _all_ aliases, not just
+ the active and connected ones.
+
+
+ modified files:
+ eicq.el
+
+
+2006-01-15 15:55:02 GMT Steve Youngs <steve@sxemacs.org> patch-3
+
+ Summary:
+ Remove `eicq-extra-buffers-to-kill'
+ Revision:
+ eicq--main--0.9--patch-3
+
+ * eicq-log.el (eicq-log-update-history): No need to add anything to
+ `eicq-extra-buffers-to-kill'.
+ (eicq-extra-buffers-to-kill): Removed.
+
+ * eicq.el (eicq-exit): `eicq-extra-buffers-to-kill' isn't used anymore.
+ (eicq-logout): Ditto.
+
+
+ modified files:
+ eicq-log.el eicq.el
+
+
+2006-01-15 02:01:06 GMT Steve Youngs <steve@eicq.org> patch-2
+
+ Summary:
+ Save history after each message
+ Revision:
+ eicq--main--0.9--patch-2
+
+ This changeset means that the history files will be saved after each
+ message is appended to them, instead of just when you log out. The
+ "Wrote: /foo/bar/file" messages have been suppressed.
+
+ It means that when I kill my SXEmacs without logging out of Eicq my
+ history directory doesn't have those "#file#" backups and I don't get the
+ "Consider recover-file" messages next time I log in.
+
+ * eicq-log.el (eicq-log-update-history): Save the history files after
+ each message but use `write-region' so we can suppress those annoying
+ "Wrote: /foo/bar/file" messages.
+
+
+ modified files:
+ eicq-log.el
+
+
+2005-12-26 04:59:25 GMT Steve Youngs <steve@eicq.org> patch-1
+
+ Summary:
+ Merged versionfix-1 from 2005 repo, Prepare for 0.9 cycle
+ Revision:
+ eicq--main--0.9--patch-1
+
+ * NEWS: Update, prepare for 0.9 release cycle
+
+ * Makefile (VER): Bump to 0.9
+
+
+ Patches applied:
+
+ * steve@eicq.org--2005/eicq--main--0.8--versionfix-1
+ Oops, forgot to update the NEWS file.
+
+
+
+ new files:
+ ChangeLog.d/.arch-ids/ChangeLog-0.8.id
+ ChangeLog.d/ChangeLog-0.8
+
+ modified files:
+ Makefile NEWS
+
+ new patches:
+ steve@eicq.org--2005/eicq--main--0.8--versionfix-1
+
+
+2005-12-26 03:48:33 GMT Steve Youngs <steve@eicq.org> base-0
+
+ Summary:
+ tag of steve@eicq.org--2005/eicq--main--0.8--version-0
+ Revision:
+ eicq--main--0.9--base-0
+
+ (automatically generated log message)
+
+ new patches:
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-1
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-2
+ dev@xwem.org--2004-w/eicq--ckent--0.7--patch-3
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-1
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-2
+ karma@sxemacs.org--2005/eicq--karma--0.7--patch-4
+ lg@xwem.org--2005/eicq--lg--0.7--patch-1
+ lg@xwem.org--2005/eicq--lg--0.7--patch-2
+ lg@xwem.org--2005/eicq--lg--0.7--patch-5
+ lg@xwem.org--2005/eicq--lg--0.7--patch-8
+ lg@xwem.org--2005/eicq--lg--0.7--patch-9
+ lg@xwem.org--2005/eicq--lg--0.7--patch-12
+ lg@xwem.org--2005/eicq--lg--0.7--patch-13
+ lg@xwem.org--2005/eicq--lg--0.7--patch-14
+ lg@xwem.org--2005/eicq--lg--0.7--patch-16
+ lg@xwem.org--2005/eicq--lg--0.7--patch-18
+ lg@xwem.org--2005/eicq--lg--0.7--patch-19
+ lg@xwem.org--2005/eicq--lg--0.7--patch-20
+ lg@xwem.org--2005/eicq--lg--0.7--patch-21
+ lg@xwem.org--2005/eicq--lg--0.7--patch-23
+ lg@xwem.org--2005/eicq--lg--0.7--patch-28
+ lg@xwem.org--2005/eicq--lg--0.8--patch-1
+ lg@xwem.org--2005/eicq--lg--0.8--patch-2
+ lg@xwem.org--2005/eicq--lg--0.8--patch-3
+ lg@xwem.org--2005/eicq--lg--0.8--patch-4
+ steve@eicq.org--2004/eicq--main--0.6--base-0
+ steve@eicq.org--2004/eicq--main--0.6--patch-1
+ steve@eicq.org--2004/eicq--main--0.6--patch-2
+ steve@eicq.org--2004/eicq--main--0.6--patch-3
+ steve@eicq.org--2004/eicq--main--0.6--patch-4
+ steve@eicq.org--2004/eicq--main--0.6--patch-5
+ steve@eicq.org--2004/eicq--main--0.6--patch-6
+ steve@eicq.org--2004/eicq--main--0.6--patch-7
+ steve@eicq.org--2004/eicq--main--0.6--patch-8
+ steve@eicq.org--2004/eicq--main--0.6--patch-9
+ steve@eicq.org--2004/eicq--main--0.6--patch-10
+ steve@eicq.org--2004/eicq--main--0.6--patch-11
+ steve@eicq.org--2004/eicq--main--0.6--patch-12
+ steve@eicq.org--2004/eicq--main--0.6--patch-13
+ steve@eicq.org--2004/eicq--main--0.6--patch-14
+ steve@eicq.org--2004/eicq--main--0.6--patch-15
+ steve@eicq.org--2005/eicq--main--0.7--base-0
+ steve@eicq.org--2005/eicq--main--0.7--patch-1
+ steve@eicq.org--2005/eicq--main--0.7--patch-2
+ steve@eicq.org--2005/eicq--main--0.7--patch-3
+ steve@eicq.org--2005/eicq--main--0.7--patch-4
+ steve@eicq.org--2005/eicq--main--0.7--patch-5
+ steve@eicq.org--2005/eicq--main--0.7--patch-6
+ steve@eicq.org--2005/eicq--main--0.7--patch-7
+ steve@eicq.org--2005/eicq--main--0.7--patch-8
+ steve@eicq.org--2005/eicq--main--0.7--patch-9
+ steve@eicq.org--2005/eicq--main--0.7--patch-10
+ steve@eicq.org--2005/eicq--main--0.7--patch-11
+ steve@eicq.org--2005/eicq--main--0.7--patch-12
+ steve@eicq.org--2005/eicq--main--0.7--patch-13
+ steve@eicq.org--2005/eicq--main--0.7--patch-14
+ steve@eicq.org--2005/eicq--main--0.7--patch-15
+ steve@eicq.org--2005/eicq--main--0.7--patch-16
+ steve@eicq.org--2005/eicq--main--0.7--patch-17
+ steve@eicq.org--2005/eicq--main--0.7--patch-18
+ steve@eicq.org--2005/eicq--main--0.7--patch-19
+ steve@eicq.org--2005/eicq--main--0.7--patch-20
+ steve@eicq.org--2005/eicq--main--0.7--patch-21
+ steve@eicq.org--2005/eicq--main--0.7--patch-22
+ steve@eicq.org--2005/eicq--main--0.7--patch-23
+ steve@eicq.org--2005/eicq--main--0.7--patch-24
+ steve@eicq.org--2005/eicq--main--0.7--patch-25
+ steve@eicq.org--2005/eicq--main--0.7--patch-26
+ steve@eicq.org--2005/eicq--main--0.7--patch-27
+ steve@eicq.org--2005/eicq--main--0.7--patch-28
+ steve@eicq.org--2005/eicq--main--0.7--patch-29
+ steve@eicq.org--2005/eicq--main--0.7--patch-30
+ steve@eicq.org--2005/eicq--main--0.7--patch-31
+ steve@eicq.org--2005/eicq--main--0.7--patch-32
+ steve@eicq.org--2005/eicq--main--0.7--patch-33
+ steve@eicq.org--2005/eicq--main--0.7--patch-34
+ steve@eicq.org--2005/eicq--main--0.7--patch-35
+ steve@eicq.org--2005/eicq--main--0.7--patch-36
+ steve@eicq.org--2005/eicq--main--0.7--patch-37
+ steve@eicq.org--2005/eicq--main--0.7--patch-38
+ steve@eicq.org--2005/eicq--main--0.7--patch-39
+ steve@eicq.org--2005/eicq--main--0.7--patch-40
+ steve@eicq.org--2005/eicq--main--0.7--patch-41
+ steve@eicq.org--2005/eicq--main--0.7--patch-42
+ steve@eicq.org--2005/eicq--main--0.7--patch-43
+ steve@eicq.org--2005/eicq--main--0.7--patch-44
+ steve@eicq.org--2005/eicq--main--0.7--patch-45
+ steve@eicq.org--2005/eicq--main--0.7--patch-46
+ steve@eicq.org--2005/eicq--main--0.7--patch-47
+ steve@eicq.org--2005/eicq--main--0.7--patch-48
+ steve@eicq.org--2005/eicq--main--0.7--patch-49
+ steve@eicq.org--2005/eicq--main--0.7--patch-50
+ steve@eicq.org--2005/eicq--main--0.7--patch-51
+ steve@eicq.org--2005/eicq--main--0.7--patch-52
+ steve@eicq.org--2005/eicq--main--0.7--patch-53
+ steve@eicq.org--2005/eicq--main--0.7--patch-54
+ steve@eicq.org--2005/eicq--main--0.7--patch-55
+ steve@eicq.org--2005/eicq--main--0.7--patch-56
+ steve@eicq.org--2005/eicq--main--0.7--patch-57
+ steve@eicq.org--2005/eicq--main--0.7--patch-58
+ steve@eicq.org--2005/eicq--main--0.7--patch-59
+ steve@eicq.org--2005/eicq--main--0.7--patch-60
+ steve@eicq.org--2005/eicq--main--0.7--version-0
+ steve@eicq.org--2005/eicq--main--0.8--base-0
+ steve@eicq.org--2005/eicq--main--0.8--patch-1
+ steve@eicq.org--2005/eicq--main--0.8--patch-2
+ steve@eicq.org--2005/eicq--main--0.8--patch-3
+ steve@eicq.org--2005/eicq--main--0.8--patch-4
+ steve@eicq.org--2005/eicq--main--0.8--patch-5
+ steve@eicq.org--2005/eicq--main--0.8--patch-6
+ steve@eicq.org--2005/eicq--main--0.8--patch-7
+ steve@eicq.org--2005/eicq--main--0.8--patch-8
+ steve@eicq.org--2005/eicq--main--0.8--patch-9
+ steve@eicq.org--2005/eicq--main--0.8--patch-10
+ steve@eicq.org--2005/eicq--main--0.8--patch-11
+ steve@eicq.org--2005/eicq--main--0.8--patch-12
+ steve@eicq.org--2005/eicq--main--0.8--patch-13
+ steve@eicq.org--2005/eicq--main--0.8--patch-14
+ steve@eicq.org--2005/eicq--main--0.8--patch-15
+ steve@eicq.org--2005/eicq--main--0.8--patch-16
+ steve@eicq.org--2005/eicq--main--0.8--patch-17
+ steve@eicq.org--2005/eicq--main--0.8--patch-18
+ steve@eicq.org--2005/eicq--main--0.8--patch-19
+ steve@eicq.org--2005/eicq--main--0.8--patch-20
+ steve@eicq.org--2005/eicq--main--0.8--patch-21
+ steve@eicq.org--2005/eicq--main--0.8--patch-22
+ steve@eicq.org--2005/eicq--main--0.8--patch-23
+ steve@eicq.org--2005/eicq--main--0.8--version-0
+
+
--- /dev/null
+
+========================================================================
+EMchat is now written entirely in emacs-lisp, so theoretically it should
+run on anything that can run (S)XEmacs and can connect to the ICQ servers.
+
+You will need at least XEmacs 21.4 or any version of SXEmacs.
+========================================================================
+
+This installation is definitely a 'no-brainer'
+
+1) Check the Makefile, and edit anything as required.
+
+ On Windows, you must have set your HOME variable (e.g. on Windows 98
+ in your autoexec.bat, add 'set HOME=C:\' before installation. You
+ should have set HOME for Cygwin anyway). Reboot if necessary before
+ installing EMchat!
+
+ For Cygwin, search for '# Cygwin #' in the Makefile and to see what
+ you need to change to build on Cygwin.
+
+ For Solaris, search for '# Solaris #' in the Makefile to see what
+ you need to change to build on Solaris.
+
+2) 'make'
+
+3) become 'root' and then 'make install'. On Windows just type
+ 'make install'
+
+Hold it, you're not finished yet...
+
+Add the following to your `user-init-file' (XEmacs -- ~/.xemacs/init.el
+ SXEmacs -- ~/.sxemacs/init.el)
+---------- cut ----------
+
+(require 'emchat)
+(setq emchat-user-alias "me")
+
+
+---------- cut ----------
+
+As the user that will be using EMchat, fire up (S)XEmacs and...
+
+M-x emchat-setup RET
+
+That will set up the needed stuff in your home directory.
+
+Adding your own UIN:
+-------------------
+~/.emchat/world is the file that stores not only the UIN's of your
+friends but also your own UIN.
+
+Just edit ~/.emchat/world and change the UIN beside 'me' to reflect your
+own UIN.
+
+Of course you can change the alias ('me') of your own UIN to be whatever
+you want. But you'll have to change the (setq emchat-user-alias "...")
+line in your `user-init-file' to match.
+
+
+Ok, now you're done.
+
+'M-x emchat-login'. There you go!
+
+Don't hesitate to message me a success report or mail me your
+screenshots!
+
+
+Example world file:
+------------------
+Literally you can put anything you like in this resource file, such as
+this introduction. EMchat will only consider a line to be a valid buddy
+if...
+
+ -- `:icq' starts at column zero (there's no leading whitespace or
+ characters).
+
+ -- There is one space between `:icq' and a UIN.
+
+ -- There is one space between a UIN and a buddy name.
+
+ -- The buddy name does NOT contain any colon `:' characters.
+ Buddy names can contain whitespace anywhere except as the
+ first character.
+
+ -- There is one space between the buddy name and any group names.
+ Group names begin with a colon `:'.
+
+So, for example...
+
+:icq 34307457 emchat
+:icq 12345678 me
+:icq 88888888 the queen :royalty
+
+This way, it defines three buddies: \"emchat\", \"me\", and \"the
+queen\". It reads alias name until the end of the line, or until the
+first group name. In that example, the buddy \"the queen\" is in
+the group `:royalty'.
+
+Adding your own UIN:
+
+Just change \"12345678 me\" above to your UIN/alias. And don't
+forget to change the (setq emchat-user-alias \"me\") line in your
+`user-init-file' to match.
+
+BTW, that 1st buddy up there, 34307457 emchat, is a valid UIN, it's
+mine. :-)
+
+Remember to M-x emchat-world-update after changing this rc file.
+
--- /dev/null
+## Makefile for EMchat -*-Makefile-*-
+##
+## Copyright (C) 2001 - 2008 Steve Youngs
+##
+## This file is part of EMchat.
+
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions
+## are met:
+##
+## 1. Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+##
+## 2. Redistributions in binary form must reproduce the above copyright
+## notice, this list of conditions and the following disclaimer in the
+## documentation and/or other materials provided with the distribution.
+##
+## 3. Neither the name of the author nor the names of any contributors
+## may be used to endorse or promote products derived from this
+## software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+## IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+## WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+## DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+## SUBSTITUTE GOODS OR SERVICES# LOSS OF USE, DATA, OR PROFITS# OR
+## BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+## OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+## IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+PACKAGE = emchat
+VER = 0.9.5
+
+SHELL = /bin/sh
+# Cygwin # Comment out line above and uncomment the following line
+# SHELL = /usr/bin/sh
+
+# Cygwin # Comment out the line above and uncomment the
+# following line (/cygdrive/c is Cygwin notation for C:\ !!!)
+# PREFIX = /cygdrive/c/Program\ Files/XEmacs/site-packages
+
+# If you want to make a tarball that you can just unpack on all your
+# PC's you can 'make pkg'. The 'pkg' target uses these directories to
+# build the tarball.
+STAGING = ../build-pkg
+INFO_STAGING = $(STAGING)/info
+LISP_STAGING = $(STAGING)/lisp/$(PACKAGE)
+
+# Programs and their flags.
+ifeq ($(XEMACS),)
+ XEMACS = sxemacs
+endif
+
+XEMACS_FLAGS = -batch -no-autoloads
+MAKEINFO = makeinfo
+INSTALL = install
+# Solaris # Comment out above line and uncomment the line below
+# INSTALL = install -u 0 -g 0
+
+PKG_INSTALL = install
+TAR = /bin/tar
+TAR_FLAGS = czf
+
+# Everything hangs off this.
+ifeq ($(PREFIX),)
+ ifeq ('$(XEMACS)','sxemacs')
+ PREFIX = /usr/local/share/sxemacs/site-packages
+ else
+ ifeq ('$(XEMACS)','xemacs')
+ PREFIX = /usr/local/lib/xemacs/site-packages
+ endif
+ endif
+endif
+
+# Where the lisp files go.
+LISP_DIR = $(PREFIX)/lisp/$(PACKAGE)
+
+# logos/icons etc
+DATA_DIR = $(PREFIX)/etc/$(PACKAGE)
+
+# Where the info files go.
+INFO_DIR = $(PREFIX)/info
+
+############################################################################
+## No User Configurable Items Below Here ##
+############################################################################
+
+## Order is IMPORTANT here. Add new files to the _end_ unless you
+## know what you are doing.
+SOURCES = \
+ emchat-utils.el \
+ emchat.el \
+ emchat-buddy.el \
+ emchat-convert.el \
+ emchat-curl.el \
+ emchat-doctor.el \
+ emchat-emphasis.el \
+ emchat-history.el \
+ emchat-log.el \
+ emchat-menu.el \
+ emchat-meta.el \
+ emchat-report.el \
+ emchat-setup.el \
+ emchat-status.el \
+ emchat-toolbar.el \
+ emchat-track.el \
+ emchat-v8.el \
+ emchat-wharf.el \
+ emchat-world.el
+# emchat-xwem.el
+
+GENERATED_SRC = \
+ auto-autoloads.el \
+ custom-load.el \
+ custom-defines.el \
+
+EXTRA_SRC = INSTALL NEWS README TODO emchat-version.el
+
+OBJECTS = $(SOURCES:.el=.elc)
+GENERATED_OBJ = $(GENERATED_SRC:.el=.elc)
+TEXI_FILES = $(PACKAGE).texi
+INFO_FILES = $(TEXI_FILES:.texi=.info)
+
+DATA_FILES = $(wildcard images/*.x[pb]m) \
+ $(wildcard images/*.png)
+
+.SUFFIXES:
+.SUFFIXES: .info .texi .elc .el
+
+all:: prepsrc version compile texinfo
+
+compile:
+ $(XEMACS) $(XEMACS_FLAGS) -l "build.el"
+
+prepsrc.el:
+ @echo "(defvar srcfiles" > $@
+ @echo " (quote ($(GENERATED_SRC)" >> $@
+ @echo " $(SOURCES))))" >> $@
+
+prepsrc: prepsrc.el
+
+.texi.info:
+ $(MAKEINFO) $<
+
+texinfo: emchat-version.texi $(INFO_FILES)
+
+emchat-version.el:
+ echo ";;; Automatically generated file -- DO NOT EDIT OR DELETE" > $@
+ echo ";;;###autoload" >> $@
+ echo "(defconst emchat-version" >> $@
+ if [ -d "./{arch}" -a -x `which tla 2>/dev/null` ]; then \
+ printf ' "%s"' `tla logs -f|tail -n1` >> $@; \
+ else \
+ echo -n ' "$(VER)"' >> $@; \
+ fi
+ echo ")" >> $@
+ echo "(provide 'emchat-version)" >> $@
+
+version: emchat-version.el
+
+emchat-version.texi:
+ if [ -d "./{arch}" -a -x `which tla 2>/dev/null` ]; then \
+ printf "@set VERSION %s" `tla logs -f|tail -n1|sed s/@/@@/` > $@; \
+ else \
+ echo "@set VERSION $(VER)" > $@; \
+ fi
+
+install: all
+ $(INSTALL) -d $(INFO_DIR) $(LISP_DIR) $(DATA_DIR)
+ $(INSTALL) -m 644 $(INFO_FILES) $(INFO_DIR)
+ $(INSTALL) -m 644 $(DATA_FILES) $(DATA_DIR)
+ $(INSTALL) -m 644 $(SOURCES) $(GENERATED_SRC) $(EXTRA_SRC) \
+ $(OBJECTS) $(GENERATED_OBJ) $(LISP_DIR)
+
+# Solaris # Comment out the above and uncomment the following.
+# install: all
+# for file in $(INFO_DIR) $(LISP_DIR); \
+# do $(INSTALL) -d $$file; \
+# done
+# for file in $(INFO_FILES); \
+# do $(INSTALL) -f $(INFO_DIR) -m 644 $$file; \
+# done
+# for file in $(SOURCES) $(GENERATED_SRC) $(EXTRA_SRC) $(OBJECTS) $(GENERATED_OBJ); \
+# do $(INSTALL) -f $(LISP_DIR) -m 644 $$file; \
+# done
+
+
+pkg: all
+ $(PKG_INSTALL) -d $(STAGING) $(INFO_STAGING) $(LISP_STAGING)
+ $(PKG_INSTALL) -m 644 $(INFO_FILES) $(INFO_STAGING)
+ $(PKG_INSTALL) -m 644 $(SOURCES) $(GENERATED_SRC) $(EXTRA_SRC) \
+ $(OBJECTS) $(GENERATED_OBJ) $(LISP_STAGING)
+ (cd $(STAGING); \
+ $(TAR) $(TAR_FLAGS) $(PACKAGE)-$(VER)-pkg.tar.gz ./*)
+
+upgrade: distclean uninstall install
+
+uninstall::
+ rm -rf $(LISP_DIR)
+ rm -f $(INFO_DIR)/$(INFO_FILES)
+
+clean::
+ rm -f $(OBJECTS) $(GENERATED_OBJ) $(GENERATED_SRC) \
+ $(INFO_FILES)
+
+
+distclean: clean
+ rm -f core* *~ TAGS emchat-version.el emchat-version.texi \
+ prepsrc.el
+
+# Developer targets
+tags: TAGS
+
+TAGS: $(SOURCES)
+ etags $(SOURCES)
+
+.PHONY: emchat-version.el version emchat-version.texi
--- /dev/null
+-*- Outline -*-
+
+* 0.9.2 to 0.9.3 (First EMchat release)
+
+* 0.9.1
+
+This was the last Eicq release. From this point on it is EMchat.
+Oh, and sorry for not updating this file in the last couple of
+versions.
+
+* 0.8 to 0.9
+
+* 0.7 to 0.8
+
+- Removed all the old stagnating v5 protocol code. (Me)
+- GUI enhancements (Me)
+ Removed some unnecessary scrollbars
+ Optionally use the gutter tabs instead of the status buffer
+ Display X-Face and Colour Face images in buddy buffer
+- Fix bug with Eicq trying to play undefined sounds. (Me)
+- Better handling of switching between log/buddy buffers (Me).
+- Add an "oops" function. (Me)
+ This is for those times when you send a msg to the wrong
+ person, `eicq-oops', sends the msg to the right person and an
+ apology/explanation to the wrong person.
+- Eliza meets Eicq. (Me)
+ As far as we are aware, Eicq is the only ICQ client in the
+ world that allows your contacts to psycho-analyze themselves.
+- Activity indicatory for XWEM. (Me)
+ Displays a small glyph in the xwem-minibuffer. The glyph
+ changes when you have new incoming messages.
+- Fix bug that was causing `current-buffer' to be screwed after an
+ auto-relogin. (Me)
+- Support Russian language out of the box. (Evgeny Zajcev)
+- Key binding fix. (Evgeny Zajcev)
+- BBDB fix. (Evgeny Zajcev, Me)
+
+* 0.6 to 0.7
+
+- Protocol code fixes/additions (Evgeny Zajcev, Me)
+ Way too many changes to list here. Suffice to say that in
+ this release, Eicq went from non-working bitrot to usable and
+ functioning ICQ client! :-) See the README file for a summary
+ of the currently working features.
+- Log buffer enhancements (aka Gnus-style emphasis) (Me)
+ Underline, bold, italic text. Hyperlinked URL's, email
+ addresses and Unix manual page names.
+- Auto-response messages improvements (Me)
+ Auto-responses are only sent once per contact per period of
+ not being in the "online" status. Can also set some contacts
+ to never receive these auto-responses.
+- Allow other ICQ user to request "online notifications" (Me)
+ This works by the other user sending you a message with the
+ magic string ",,notify-me" in the message, and when you next
+ change status to "online", anyone who has sent you the magic
+ string gets sent a message saying you're back online.
+- Global key prefix (default is M-`) customisable (Me)
+ Also most of the previously globally bound keys have been
+ removed from the global map. Now all that is in the global
+ map is what is really needed, things like eicq-login and
+ eicq-show-window.
+- Contact names appear in buddy buffer in the same order as world (ME)
+- Contact histories (Alexey Mikhailov)
+ Adds mICQ-style history for each contact. Turn it on with:
+ (setq eicq-history-enabled-flag t)
+- Eicq-track (Alexey Mikhailov)
+ ERC/Riece style modeline indicator.
+- Handle "invisible" status correctly (Me)
+ This is something that Eicq has never done right, up until
+ now. It is possible to be invisible _and_ online or away or
+ na etc.
+- Make Eicq usable on a TTY/console (Me)
+ Who says you need a GUI to chat on ICQ? :-)
+
+* 0.5.9 to 0.6
+
+- Switch from n.n.n to n.n version numbers.
+ Actually, these n.n version numbers are only seen on the
+ tarball filenames etc. The version string you see from
+ M-x eicq-version looks like:
+
+ Eicq: steve@eicq.org--2005/eicq--main--0.6--patch-15
+
+- Development was moved away from SF.net and is now done all
+ "in-house" at eicq.org.
+- Switched to GNU/Arch version control instead of CVS.
+- Many additions/fixes to protocol code (Evgeny Zajcev, Me)
+- Make it easy for people to donate to the project (Me)
+ M-x eicq-donate
+
+
+* 0.5.0 to 0.5.9
+
+- Switched to BSD license.
+
+* 0.2.17 to 0.5.0
+
+- Major cleanup and restructuring (Me)
+ Lots and lots of stuff has changed, see the ChangeLog for all
+ the gory details. Oh, it would be a REALLY GOOD IDEA if you
+ remove any previous version of Eicq BEFORE you install this
+ one. Yes, it's changed THAT much.
+
+ We haven't achieved ICQv8 protocol compliance yet, but
+ hopefully, we'll be at least partially there with this
+ release.
+
+* 0.2.16 to 0.2.17
+
+- Auto-reconnect (Me)
+ Don't attempt to reconnect if a password isn't set or if
+ delete-offline-messages is set to 'ask.
+- Buddy buffer reset to pre-logged-in-state on logout. (Me)
+- eicq-connect/disconnect cleanup (Erik Arneson, Me)
+- New function 'eicq-search-by-uin' (Me)
+ Search for a user by their ICQ number.
+- New function 'eicq-add-user' (Me)
+ Dynamically add a new contact to you buddy list.
+- Eicq is now "web-aware" capable. (Me)
+- EicqWharf cleanup (Erik Arneson)
+ Don't try to do anything unless the Wharf frame has been
+ created.
+
+
+* 0.2.15 to 0.2.16
+
+- Bug report code cleanup/enhancement. (Me)
+- Use 'locate-data-directory' to find data files. (Me)
+- eicq-wharf.el New file (Erik Arneson)
+ Create a tiny frame suitable for docking. Keeps track of
+ number of new messages.
+- New hooks to use with eicq-wharf.el (Me)
+- 2nd set of auto-response messages (Me)
+ To be used when you have idled away as opposed to explicitly
+ marking yourself away (not yet working).
+- Cleaner layout for query output. (Me)
+- Remove background colour settings. (Me)
+- Auto-reconnect if kicked off ICQ server. (Me)
+- Don't log outgoing auto-response messages. (Me)
+- Optionally auto-save the log file on exiting Eicq. (Me)
+
+* 0.2.14 to 0.2.15
+
+- Cygwin builds (Thorsten Bonow)
+ Add cygwin related comments to Makefile, INSTALL,
+ eicq-user-install.sh
+- New file 'eicq-convert.el' (Erik Arneson)
+ Convert Licq and Micq contact lists to Eicq 'world' format.
+- Makefile improvements (Erik Arneson).
+- icq2tcp.c (Erik Arneson)
+ Ported from the C++ icq2tcp.cc to ANSI C
+- Better handling of remote bridges (Erik Arneson).
+- Optionally start Eicq in its own frame (Erik Arneson).
+- Implement auto-response messages (Me).
+- Update URLs to reflect SourceForge's new domain 'sf.net'(Me).
+- Solaris builds (Jack Twilley)
+ Add needed changes to Makefile to build on Solaris.
+
+* 0.2.13 to 0.2.14
+
+- Rewrote the bug report code.
+ It now reports any user variable that has be changed
+ from the default.
+- eicq-version now accepts arg.
+ So C-u M-x eicq-version RET will insert the version string
+ in the current buffer at point.
+- Added type boolean to all the 'on/off' defcustoms.
+- Removed some obsolete v2 stuff.
+- Renamed udp2tcp.cc to icq2tcp.cc
+- Added new target "pkg" to Makefile
+ It builds Eicq and creates a tarball that can be used to
+ install Eicq simply by unpacking the tarball into the
+ appropriate directory.
+
+
+* 0.2.12 to 0.2.13
+
+- The number of tools on toolbar reduced.
+- Statuses moved from buddy buffer to their own read-only buffer.
+- Smilies
+- URL/email highlighting in normal messages.
+- Can turn sounds off/on.
+
+* 0.2.11 to 0.2.12
+
+- Change status via widgets in the buddy buffer.
+- In log buffer:
+ 'n' move to next unread message
+ 'p' move to previous unread message
+ 'N' move to next message (whether read or unread)
+ 'P' move to previous message (whether read or unread)
+ Outgoing messages are automatically marked as read.
+- Auto away/na timeouts now work correctly.
+- Auto online after a auto away/na.
+- Use the same toolbar in both the log and buddy buffers.
+- M-x eicq-login automatically brings up the buddy and log buffers.
+- The toolbar button "Disconnect":
+ Does a 'eicq-logout'
+ Kills the Eicq buffers.
+
+* 0.2.10 to 0.2.11
+
+- 'eicq-report-bug' now working.
+
+* 0.2.9 to 0.2.10
+
+- No longer distributed as an XEmacs package (due to compatibility issues)
+- Re-arrange variables so that everything compiles cleanly with no errors.
+- Uses XEmacs to create the info documentation.
+
+* 0.2.8 to 0.2.9
+
+- New function 'eicq-report-bug'
+- 'eicq-email-author' uses Gnus if available.
+
+* 0.2.5 to 0.2.8
+
+- Mainly just doc fixes.
+
+* 0.2.4 to 0.2.5
+
+- entered into the mainstream XEmacs packages
+
+* 0.2.3 to 0.2.4
+
+- clickety click toolbars
+- new locations for files (a system wide approach)
+- more sound
+
+* 0.2.2 to 0.2.3
+
+- sound added
+
+* 0.2.1 to 0.2.2
+
+- highlight alias and url (from Erik)
+- world-mode
+- eicq-change-user, eicq-hide-window
+
+* 0.2.0 to 0.2.1
+
+- remove relogin, more stable
+
+* 0.1.3 to 0.2.0
+
+- ICQ version 5 protocol
+- meta user info query and update
+- register new user, change password
+- receive contact list transfer
+- forward message
+- more stable (less kicked out)
+
+* 0.1.2 to 0.1.3
+
+- restructure of eicq-world
+- use resource file instead of lisp structure
+- new files in package: NEWS and world (resource file)
+- alias selection as temporary group
+- fixed random popping up uin
+- safer udp2tcp: use length prefix instead of delimiting magic string
+- eicq-do-status-update-hook and eicq-do-message-hook for customization
+- split and send long messages
+- search users, update basic info and extended info
+- relogin quiently after being kicked out
+- auto-na
+
+
--- /dev/null
+-*- outline -*-
+
+* Introduction
+
+http://www.emchat.org/INSTALL
+
+This file is best viewed under (S)XEmacs. Press C-c C-o now to
+see the outline of topics. You can use (S)XEmacs menu to
+navigate and hide/show different topics. (C-c means Control
+and c; M-x means Meta and x.)
+
+I publish this package in the hope of making more people
+appreciate (S)XEmacs and Lisp.
+
+You can contact me for anything at <steve@emchat.org>
+
+* Feature list
+
+- EMchat is written entirely in elisp
+- EMchat uses the latest version of the ICQ protocol. (OSCAR)
+- Send/receive messages
+- Send/receive URL type messagse
+- Send/Receive authorisation request messages
+- Approve/Decline incoming auth requests
+- Query ICQ users' meta info
+- Search for ICQ users
+- Dynamically add new users to your contact list (recent protocol
+ changes broke this)
+- Play sounds for different events.
+- Auto online after a auto away/na.
+- Auto response away/na/dnd/occ messages.
+- Different auto response messages if EMchat has idled away/na
+- Auto reconnect if you are kicked off ICQ.
+- Gnus style smileys
+- Gnus style text emphasis (underline, bold, italic, etc)
+- "Clickable" hyperlinks for URL's, email addresses, and Unix manual page titles
+- climm (mICQ) style per contact history logs
+- ERC/Riece style modeline activity indicator
+- Works in both a GUI environment and on a console/TTY (even both at the same time)
+- A dockable frame that tracks the number of unread messages.
+- Interactive customisation through (S)XEmacs Custom widgets.
+- Key binding, "scripting" in elisp.
+- Allow other users/contacts to psycho-analyse themselves
+- Display X-Face/Colour Face header images in buddy buffer.
+- An "oops" function
+- Customisable semi-automation
+
+
+EMchat cannot yet transfer files, chat, or anything that requires a
+peer-to-peer direct TCP connection. This is not a limitation of
+EMchat, but rather of XEmacs. As yet, XEmacs can not "listen" for an
+incoming TCP connection.
+
+P2P _IS_ coming! SXEmacs now has server sockets, we just have to use
+em in EMchat.
+
+* Installation
+See the file 'INSTALL' in this directory.
+
+There are a few mailing lists. See <http://www.emchat.org/#maillist>
+
+Have fun!
+
+* Submitting Patches
+
+If you've got a patch for a bug fix or some wiz-bang new feature mail
+them to <emchat-devel@emchat.org>. The EMchat developers will review your
+contribution and either accept it and add it to the EMchat code, or
+reject it. Whether accepted or rejected, you'll hear back from us.
+
+Please be aware though that because of spam levels the EMchat mailing
+list is a members-only posting. If you are not subscribed you'll have
+to wait for the moderator to process your post. Please be patient,
+he's a rilly busy guy. :-)
+
+* Faq and tips
+
+** password
+
+How to save password?
+
+M-x customize-variable RET emchat-user-password
+Or simply, (setq emchat-user-password "mypassword") in your
+`user-init-file'.
+
+** "M" vs "m" (send-message)
+
+Commands in capital letters prompt you for aliases/uin while
+those in small letters search for aliases/uin around the
+cursor in emchat buffers, and perform actions on them. For
+example, "m" inside an incoming message acts like a reply.
+
+** alias vs uin
+
+"JackaLX" is my alias while "34307457" is my uin. In all prompts
+of entering an icq person, you can enter either an alias or
+an uin, although only alias completing read is provided.
+(Press TAB when entering an alias!)
+
+** message/alias history
+
+Use M-p/M-n or UP/DOWN to navigate history in prompts of
+entering alias or messages.
+Use M-r/M-s to search history.
+
+** log file size
+
+Watch out for monster emchat-log buffer size! Use M-x
+emchat-log-new-file occasionally.
+
+As of version 0.2.16 Eicq will automatically save the log file when
+you disconnect from ICQ. You can change this behaviour with
+'M-x emchat-customize' in the 'emchat-log' group.
+
+** hooks
+
+If you want to customize anything fancy:
+
+emchat-buddy-mode-hook
+emchat-log-mode-hook
+emchat-new-message-hook
+emchat-read-message-hook
+emchat-status-update-hook
+emchat-system-message-hook
+
+** Using EMchatWharf
+
+EMchatWharf is a tiny frame that shows the number of unread messages you
+have. It is suitable for docking into the GNOME panel (YMMV). I use
+it with Sawfish WM (in a "sawlet" dockapp thingy). And I've also used
+EMchatWharf in FVWM by simply setting the geometry and making it
+sticky from my FVWM rc file.
+
+To get the EMchatWharf frame put into your (S)XEmacs init file:
+
+(require 'emchat-wharf)
+(setq emchat-wharf-frame-use-p t)
+(add-hook 'emchat-new-message-hook #'emchat-wharf-inc-messages)
+(add-hook 'emchat-system-message-hook #'emchat-wharf-inc-system)
+(add-hook 'emchat-read-message-hook #'emchat-wharf-dec-messages)
+
+*** Add Riece integration to EMchatWharf
+
+Riece is a VERY good emacs IRC client (I highly recommend it). If
+you'd like to know when there is activity in your Riece frame, you can
+have EMchatWharf tell you. All you have to do is add this to the
+above EMchatWharf settings...
+
+(setq emchat-wharf-notice-riece-flag t)
+(add-hook 'riece-biff-activity-hook #'emchat-wharf-riece-active)
+(add-hook 'riece-biff-clear-hook #'emchat-wharf-riece-inactive)
+
+And then turn on riece-biff in your Riece settings
+
+** EMchat in its own frame
+
+You can optionally start EMchat in its own frame with:
+
+(setq emchat-start-in-new-frame t)
+
+** Using EMchat-Track
+
+EMchat-Track is a modeline indicator that tells you when you have new
+messages. To turn it on, just put in your (S)XEmacs init file:
+
+(setq emchat-track-enable t)
+
+** Using EMchat-History
+
+EMchat-History are per contact history files. Basically individual logs
+for each contact. Turn it on with:
+
+(setq emchat-history-enabled-flag t)
+
+** Displaying X-Face or colour Face Images in buddy buffer
+
+You can display X-Face images (or colour face images) in the buddy
+buffer, but it does require a little setting up, both in EMchat and in
+BBDB.
+
+*** EMchat Setup
+
+This is the easy part, all you need to do is:
+
+ (setq emchat-buddy-show-xface t)
+
+*** BBDB Setup
+
+First of all, you need a new field called "icqnick" for each EMchat
+contact that is in your BBDB. This field's value is the alias name
+from EMchat (the name displayed in the buddy buffer).
+
+ M-x bbdb-insert-new-field RET icqnick RET
+
+ answer `yes' to the prompt about `icqnick' isn't a known field,
+ define it?
+
+ Then just give it the desired value (contact name)
+
+You'll also have to set up BBDB to collect X-Face and colour face
+headers from your mail. For some docs on how to do that, see:
+
+ <http://www.emacswiki.org/cgi-bin/wiki/BbdbFaces>
+
+** newline
+
+How to enter new lines in minibuffer?
+
+ Type 'Hello C-q 12 World'
+
+To get:
+
+ Hello
+ world
+
+** (S)XEmacs Init File tips
+
+(resize-minibuffer-mode 1)
+
+
--- /dev/null
+-*- outline -*-
+
+* Last Updated: June 14, 2005
+
+Disregard the date there, this file is hideously out of date, it will
+be fixed up in the next release.
+
+Here's a list of things I may or may not get around to putting
+into EMchat.
+
+This list is not in order of importance or any kind of order at all.
+And just because something is on the list doesn't mean that it will
+become part of EMchat.
+
+Feel free to do any of these things and send a patch to
+<emchat-devel@emchat.org>
+
+* Todo list
+
+** Direct TCP, file transfer/chat.
+
+ Can't do this until (S)XEmacs has server sockets.
+
+** Pop-up/permanent window for entering long message.
+
+** Store offline messages and send them when online.
+
+** Security problem of `emchat-user-password' in init file.
+
+** Openssl support.
+
+** Do something useful with the 'group' code.
+
+ Send message to multiple contacts etc etc.
+
+** Ignore that annoying spammer!
+
+ There are definitely times when you'd rather not hear what
+ someone has to say. Mwuahahah!
+
+** Triggers
+
+ Imagine running an elisp defun whenever an EMchat message matching
+ a particular regular expression comes in. This functionality
+ will need to be documented carefully due to the security
+ implications, of course.
+
+** Externally triggered messages
+
+ biff meets EMchat. "Hey, you just got some email. You better
+ read it." Or maybe "The power is out and your UPS just kicked
+ on.". The sky is the limit.
+
+** PostgreSQL support
+
+ Take advantage of XEmacs' PostgreSQL support for storing and
+ retrieving all kinds of useless data about your contacts.
+
+
--- /dev/null
+;;; build.el --- Builds EMchat.
+;;
+;; Copyright (C) 2006 Sebastian Freundt
+;; Copyright (C) 2007 Steve Youngs
+;;
+;; Author: Sebastian Freundt <hroptatyr@sxemacs.org>
+;; Maintainer: EMchat Development Team
+;; Keywords: internal
+;;
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;;
+;;; Synched up with: Not in FSF.
+
+;;; Commentary:
+;;
+;; This file is only used during EMchat builds, it does what the name
+;; implies... builds the lisp, plus it generates auto-autoloads.el,
+;; custom-load.el and custom-define.el files.
+
+;;; Code:
+(setq stack-trace-on-error t)
+
+(defvar wd default-directory)
+(push wd load-path)
+
+(defvar needed '(cus-dep autoload bytecomp byte-optimize font))
+(mapcar #'require needed)
+
+(defalias #'executable-find #'ignore)
+
+(let ((pname "emchat")
+ (adir wd))
+ (update-autoload-files adir pname)
+ (Custom-make-dependencies adir)
+ (update-custom-define-files adir pname))
+
+(load "prepsrc")
+
+(mapcar
+ #'(lambda (sym)
+ (let ((file (symbol-name sym)))
+ (when (string= file "custom-defines.el")
+ (autoload 'emchat-emphasis-custom-with-format
+ "emchat-emphasis" nil nil 'macro))
+ (byte-compile-file (expand-file-name file wd))))
+ srcfiles)
+
+;; indicate success
+(kill-emacs 0)
+
+;;; build.el ends here
--- /dev/null
+;;; emchat-buddy.el --- "Buddy" code for EMchat
+
+;; Copyright (C) 2007 Steve Youngs
+
+;; Author: Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created: 2002-10-01
+;; Homepage: http://www.emchat.org/
+;; Keywords: comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(eval-and-compile
+ (require 'emchat-menu)
+ (require 'emchat-status)
+ (require 'emchat-world)
+ (require 'emchat-history))
+
+(eval-when-compile
+ (require 'advice)
+ (require 'bbdb))
+
+(defgroup emchat-buddy nil
+ "Contact list preferences."
+ :group 'emchat)
+
+;;;###autoload
+(defcustom emchat-buddy-window-width 20
+ "*Width of window for `emchat-buddy-buffer'."
+ :group 'emchat-interface)
+
+(defcustom emchat-buddy-view
+ 'emchat-connected-aliases
+ "*View of buddy buffer.
+It determines what aliases to be display in buddy buffer. For example,
+\(emchat-connected-aliases) means display all connected aliases.
+
+See `emchat-buddy-view-all', `emchat-buddy-view-connected', and
+`emchat-buddy-view-active'."
+ :group 'emchat-buddy
+ :type '(choice (item emchat-all-aliases)
+ (item emchat-connected-aliases)
+ (item emchat-active-aliases))
+ :initialize 'custom-initialize-default)
+
+(defcustom emchat-buddy-show-xface nil
+ "*When non-nil, display XFace images in the buddy buffer.
+
+The images come from BBDB. For an image to display in the buddy
+buffer there has to be an existing BBDB entry for the contact that
+has both a `face' field, for the image, and a `icqnick' field, to
+match from the contact name in the buddy buffer."
+ :type 'boolean
+ :group 'emchat-buddy
+ :require 'bbdb)
+
+(defcustom emchat-buddy-prefer-cface-to-xface (featurep 'png)
+ "*When non-nil, display colour faces instead of X-Face if available."
+ :type 'boolean
+ :group 'emchat-buddy)
+
+(defface emchat-face-selected
+ '((((background dark))
+ (:foreground "darkblue" :background "yellow"))
+ (((background light))
+ (:foreground "darkblue" :background "yellow")))
+ "Face for OFFLINE status."
+ :group 'emchat-buddy)
+
+;;; Internal variables
+
+;;;###autoload
+(defvar emchat-buddy-buffer nil
+ "Buffer for contact list.")
+
+(defun emchat-buddy-mode ()
+ "Major mode for contact list in emchat.
+Commands: \\{emchat-buddy-mode-map}
+
+Turning on `emchat-buddy-mode' runs the hook `emchat-buddy-mode-hook'."
+ (interactive)
+ (kill-all-local-variables)
+ (use-local-map emchat-buddy-mode-map)
+ (setq mode-name "emchat-buddy")
+ (setq major-mode 'emchat-buddy-mode)
+ ;; put easy-menu-add after set mode-name
+ (easy-menu-add emchat-main-easymenu)
+ (easy-menu-add emchat-buddy-menu)
+ (easy-menu-add emchat-log-menu)
+ (set-specifier has-modeline-p nil
+ (cons (current-buffer) nil))
+ (set-specifier horizontal-scrollbar-visible-p nil
+ (cons (current-buffer) nil))
+ ;(setq modeline-format "%b")
+
+ (run-hooks 'emchat-buddy-mode-hook))
+
+(defun emchat-buddy-view-set (&optional symbol value)
+ "Set `emchat-buddy-view'."
+ (set-default symbol value)
+ (emchat-buddy-show-buffer 'new 'no-select))
+
+(defun emchat-face-to-png (face)
+ "Base64 decode a Face header into a PNG.
+Returns a string."
+ (with-temp-buffer
+ (insert face)
+ (base64-decode-region (point-min) (point-max))
+ (buffer-string)))
+
+(defun emchat-buddy-show-xface (alias)
+ "Display an XFace image in the buddy buffer."
+ (unless (featurep '(and xface bbdb-autoloads))
+ (error 'unimplemented "X-Face and/or BBDB"))
+ (save-excursion
+ (when (buffer-live-p emchat-buddy-buffer)
+ (set-buffer emchat-buddy-buffer)
+ (goto-char (point-min))
+ (when (search-forward-regexp (concat "^" (regexp-quote alias) "$") nil t)
+ (let ((ext (extent-at (point)))
+ (all-records (bbdb-records))
+ face cface nick record)
+ (while all-records
+ (setq record (car all-records)
+ nick (bbdb-record-getprop record 'icqnick)
+ face (bbdb-record-getprop record 'face)
+ cface (bbdb-record-getprop record 'cface))
+ (when (and (equal nick alias)
+ (or face cface))
+ ;; put some whitespace between the image and the name
+ (set-extent-begin-glyph
+ (make-extent (point-at-bol) (point-at-eol))
+ (make-glyph " "))
+ ;; Insert the X-Face
+ (when (and face
+ (or (not emchat-buddy-prefer-cface-to-xface)
+ (not cface)))
+ (set-extent-begin-glyph
+ ext
+ (make-glyph (list (vector 'xface
+ :data (concat "X-Face: " face)
+ :foreground "black"
+ :background "white")))))
+ ;; Insert the cface
+ (when (and (featurep 'png)
+ cface
+ emchat-buddy-prefer-cface-to-xface)
+ (set-extent-begin-glyph
+ ext
+ (make-glyph (list (vector 'png
+ :data (emchat-face-to-png cface)))))))
+ (setq all-records (cdr all-records))))))))
+
+;;;###autoload
+(defun emchat-buddy-show-buffer (&optional new no-select)
+ "Switch to `emchat-buddy-buffer'.
+Create buffer if buffer does not exists already or
+NEW is non-nil.
+Don't select buddy window if NO-SELECT is non-nil.
+See `emchat-buddy-view' and `emchat-buddy-status-color-hint-flag'."
+ (interactive)
+ (when (or (not (buffer-live-p emchat-buddy-buffer))
+ new)
+ (setq emchat-buddy-buffer (get-buffer-create "*emchat buddy*"))
+ (set-buffer emchat-buddy-buffer)
+ (erase-buffer)
+ (loop for alias in (symbol-value emchat-buddy-view)
+ as status = (emchat-world-getf alias 'status)
+ as face = (emchat-status-face status)
+ do (insert-face (concat alias "\n") face)
+ do (when emchat-buddy-show-xface (emchat-buddy-show-xface alias))
+ do (emchat-buddy-update-face alias))
+ (emchat-buddy-mode))
+ (unless no-select
+ (switch-to-buffer emchat-buddy-buffer)))
+
+(defun emchat-buddy-view-all ()
+ "Display all aliases in `emchat-world'.
+See `emchat-buddy-view'."
+ (interactive)
+ (emchat-buddy-view-set 'emchat-buddy-view 'emchat-all-aliases))
+
+(defun emchat-buddy-view-connected ()
+ "Display all connected aliases.
+See `emchat-buddy-view' and `emchat-connected-aliases'."
+ (interactive)
+ (emchat-buddy-view-set 'emchat-buddy-view 'emchat-connected-aliases))
+
+(defun emchat-buddy-view-active ()
+ "Display all active aliases.
+See `emchat-buddy-view' and `emchat-active-aliases'."
+ (interactive)
+ (emchat-buddy-view-set 'emchat-buddy-view 'emchat-active-aliases))
+
+(eval-when-compile (defvar emchat-history-directory))
+
+(defun emchat-buddy-show-xface-in-balloon (alias)
+ "Display an XFace image in the balloon-help buffer."
+ (unless (featurep '(and xface bbdb-autoloads))
+ (error 'unimplemented "X-Face and/or BBDB"))
+ (save-excursion
+ (let ((ext (or (extent-at (point))
+ (make-extent (point-min) (point-min))))
+ (all-records (bbdb-records))
+ face cface nick record)
+ (while all-records
+ (setq record (car all-records)
+ nick (bbdb-record-getprop record 'icqnick)
+ face (bbdb-record-getprop record 'face)
+ cface (bbdb-record-getprop record 'cface))
+ (when (and (equal nick alias)
+ (or face cface))
+ ;; put some whitespace between the image and the name
+ (set-extent-begin-glyph
+ (make-extent (point-min) (point-min))
+ (make-glyph " "))
+ ;; Insert the X-Face
+ (when (and face
+ (or (not emchat-buddy-prefer-cface-to-xface)
+ (not cface)))
+ (set-extent-begin-glyph
+ ext
+ (make-glyph (list (vector 'xface
+ :data (concat "X-Face: " face)
+ :foreground "black"
+ :background "white")))))
+ ;; Insert the cface
+ (when (and (featurep 'png)
+ cface
+ emchat-buddy-prefer-cface-to-xface)
+ (set-extent-begin-glyph
+ ext
+ (make-glyph (list (vector 'png
+ :data (emchat-face-to-png cface)))))))
+ (setq all-records (cdr all-records))))))
+
+(defadvice balloon-help-display-help (after emchat-balloon-xface (&rest args) activate)
+ "Display an X-Face or cface image in the balloon."
+ (when emchat-buddy-show-xface
+ (let ((alias (progn
+ (set-buffer balloon-help-buffer)
+ (goto-char (point-min))
+ (when (re-search-forward "\\(^.*\\) (" (eolp) t)
+ (substring (match-string 1) 1)))))
+ (when alias
+ (emchat-buddy-show-xface-in-balloon alias)))))
+
+(defun emchat-buddy-update-face (alias &optional delete)
+ "Update face of ALIAS.
+Non-nil DELETE means delete alias from buffer."
+ (save-excursion
+ (when (buffer-live-p emchat-buddy-buffer)
+ (set-buffer emchat-buddy-buffer)
+ (goto-char (point-min))
+
+ (if (search-forward-regexp
+ ;; use "^" alias "$" so searching "foo" will not get "foobar"
+ (concat "^"
+ ;; to allow funny characters in alias
+ (regexp-quote alias)
+ "$")
+ nil t)
+ ;; old alias
+ (if delete
+ (delete-region
+ (point-at-bol)
+ ;; take care of last line
+ (min (1+ (point-at-eol)) (point-max))))
+ ;; new alias
+ (unless delete
+ (insert alias "\n")
+ (forward-line -1)))
+
+ (unless delete
+ (let* ((ext (extent-at (point)))
+ (bhelp (format
+ "%s (%s)\n Status: %s\n Groups: %s\nHistory: %s\n\n\n"
+ alias
+ (emchat-alias-uin alias)
+ (or (emchat-world-getf alias 'status)
+ "offline")
+ (or (emchat-world-getf alias 'group)
+ "none")
+ (or (emchat-world-getf alias 'history)
+ "none")))
+ (face (emchat-status-face (emchat-world-getf alias 'status))))
+ (when (extentp ext)
+ (set-extent-property ext 'face face)
+ (set-extent-property ext 'balloon-help bhelp))
+
+ (when (emchat-world-getf alias 'selected)
+ ;; highlight first char
+ (put-text-property
+ (+ 0 (point-at-bol)) (+ 1 (point-at-bol))
+ 'face 'emchat-face-selected)))))))
+
+(defun emchat-buddy-select-all-in-view (state &optional predicate)
+ "Select all aliases in current view.
+See `emchat-group-select-aliases' for STATE.
+PREDICATE accepts an alias as an argument and limits the application.
+Current view is `emchat-buddy-view'."
+ (loop for x in (symbol-value emchat-buddy-view)
+ if (or (null predicate)
+ (funcall predicate x))
+ do (emchat-group-select-aliases state x)))
+
+(defun emchat-buddy-select-all-in-view-by-status (status)
+ "Toggle selections of all aliases with STATUS in current view."
+ (interactive
+ (list (emchat-completing-read "status: " emchat-valid-statuses)))
+ (emchat-buddy-select-all-in-view
+ 'toggle
+ (lambda (x)
+ (equal (emchat-world-getf x 'status) status))))
+
+(defun emchat-buddy-select-all-in-view-by-regexp (regexp)
+ "Toggle selections of all aliases matching REGEXP in current view."
+ ;; checked my screenshots? know why i use a symbol prefix now?
+ (interactive "sregexp: ")
+ (emchat-buddy-select-all-in-view
+ 'toggle
+ (lambda (x)
+ (string-match regexp x))))
+
+(defun emchat-buddy-selected-in-view ()
+ "Return a list of all selected aliases in current view.
+Selected means an alias has non-nil 'selected property.
+Current view is `emchat-buddy-view'."
+ (loop for x in (symbol-value emchat-buddy-view)
+ if (emchat-world-getf x 'selected)
+ collect x))
+
+(provide 'emchat-buddy)
+
+;;; emchat-buddy.el ends here
+
--- /dev/null
+;;; emchat-convert.el --- Utilities to convert other ICQ configurations to EMCHAT
+
+;; Copyright (C) 2001 - 2007 Steve Youngs, Erik Arneson
+
+;; OriginalAuthor: Erik Arneson <erik@aarg.net>
+;; Maintainer: Erik Arneson <erik@aarg.net>
+;; Created: Aug 06, 2001
+;; Homepage: http://www.emchat.org/
+;; Keywords: comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(eval-and-compile
+ (require 'emchat-world))
+
+;;;###autoload
+(defun emchat-import-from-licq ()
+ "Import your contact list from LICQ. It doesn't import ignored UIDs."
+ (interactive)
+ (let (uin udat user-alist ignored)
+ (setq user-alist
+ (loop for file in (directory-files
+ (expand-file-name "~/.licq/users/") t nil nil t)
+ when (file-readable-p file)
+ do (progn
+ (string-match "/\\([0-9]+\\)\\.uin$" file)
+ ;; Why can't I use 'match-string' here? Gah!
+ (setq uin (subseq file (match-beginning 1) (match-end 1)))
+ (set-buffer (find-file-noselect file))
+ ;; Need to also look for 'Groups.System = 24' to find
+ ;; out if the user is ignored.
+ (if (re-search-forward "^Groups.System = 24$" nil t)
+ (setq ignored t)
+ (setq ignored nil)
+ (goto-char (point-min))
+ ;; If an Alias is listed, use that. Otherwise, set
+ ;; the alias to the UIN.
+ (if (re-search-forward "^Alias = \\(.*\\)$" nil t)
+ (setq udat (cons uin (match-string 1)))
+ (setq udat (cons uin uin))))
+ (kill-buffer (current-buffer)))
+ when (not ignored)
+ collect udat))
+ (set-buffer (find-file-noselect (expand-file-name emchat-world-rc-filename)))
+ (goto-char (point-max))
+ (insert "\n\n==== These entries were imported from your LICQ configuration.\n")
+ (loop for udat in user-alist
+ do (insert (format ":icq %s %s :licq\n" (car udat) (cdr udat))))
+ (save-buffer (current-buffer))
+ (kill-buffer (current-buffer))))
+
+;;;###autoload
+(defun emchat-import-from-micq ()
+ "Import ICQ contact data from a .micqrc file."
+ (interactive)
+ (let (user-alist
+ unode me)
+ (set-buffer (find-file-noselect
+ (or (expand-file-name "micqrc"
+ (file-name-as-directory
+ (expand-file-name ".micq"
+ (user-home-directory))))
+ (expand-file-name ".micqrc" (user-home-directory)))))
+ (goto-char (point-min))
+ (if (re-search-forward "^UIN \\([0-9]+\\)$" nil t)
+ (setq me (match-string 1)))
+ (if (re-search-forward "^Contacts$\\|^\\[Contacts\\]$" nil t)
+ (setq user-alist
+ (loop while (re-search-forward
+ "^[ \t]*\\*?\\([0-9]+\\)[ \t]+\\(.*\\)$" nil t)
+ do (setq unode (cons (match-string 1) (match-string 2)))
+ collect unode)))
+ (kill-buffer (current-buffer))
+ (set-buffer (find-file-noselect (expand-file-name emchat-world-rc-filename)))
+ (goto-char (point-max))
+ (insert "\n\n==== These entries were imported from your MICQ configuration.\n")
+ (if me
+ (insert (format ":icq %s me\n\n" me)))
+ (loop for unode in user-alist
+ do (insert (format ":icq %s %s :micq\n" (car unode) (cdr unode))))
+ (save-buffer (current-buffer))
+ (kill-buffer (current-buffer))))
+
+;; End of file.
+
--- /dev/null
+;; emchat-curl.el --- Download files from log buffer -*- Emacs-Lisp -*-
+
+;; Copyright (C) 2007 Steve Youngs
+
+;; Author: Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created: <2007-08-31>
+;; Homepage: http://www.emchat.org/
+;; Keywords: curl download ICQ emchat file
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+;; Download stuff from URls in your log buffer via ffi-curl.el.
+;; That means you need SXEmacs to use this.
+
+;;; Todo:
+;;
+;;
+
+;;; Code:
+(eval-when-compile
+ (require 'emchat-utils)
+ (autoload #'curl:download& "ffi-curl")
+ (autoload #'curl:easy-getinfo "ffi-curl")
+ (defvar curl:errors-alist))
+
+(define-error 'emchat-curl
+ (if (featurep 'sxemacs)
+ "Your SXEmacs lacks FFI support"
+ "FFI not available in your emacs, consider upgrading to SXEmacs"))
+
+(defgroup emchat-curl nil
+ "EMchat's FFI/Curl"
+ :prefix "emchat-curl-"
+ :group 'emchat)
+
+(defcustom emchat-curl-download-directory
+ (file-name-as-directory (paths-construct-path
+ '("download") emchat-directory))
+ "*Default download directory."
+ :type 'directory
+ :group 'emchat-curl)
+
+(defcustom emchat-curl-hook-function #'emchat-curl-post-hook
+ "This function is called after a successful file download.
+
+It must accept one argument, JOB, which contains the worker-job just
+finished."
+ :type 'function
+ :group 'emchat-curl)
+
+;;; Internal variables
+
+(defvar emchat-curl-file nil)
+(defvar emchat-curl-dir nil)
+
+(defun emchat-curl-post-hook (job)
+ "Default function called after downloading files."
+ (let* ((ctx (get job 'ctx))
+ (resp (curl:easy-getinfo ctx :response-code))
+ (url (curl:easy-getinfo ctx :effective-url))
+ (speed (curl:easy-getinfo ctx :speed-download))
+ (size (curl:easy-getinfo ctx :size-download))
+ (file (expand-file-name emchat-curl-file emchat-curl-dir))
+ (resp-str (cdr (assq resp curl:errors-alist))))
+ (if resp-str
+ (emchat-log-info "Job failed: %s\nReason: %s" job resp-str)
+ (emchat-log-info
+ "Job: %s
+Detail: #<job :url <%s>
+ :local-file \"%s\"
+ :size %d bytes%s
+ :speed %s>
+"
+ job url file size
+ (cond
+ ((>= size (* 1024 1024 1024))
+ (format " (%0.2fGB)" (/ size (* 1024 1024 1024.0))))
+ ((>= size (* 1024 1024))
+ (format " (%0.2fMB)" (/ size (* 1024 1024.0))))
+ ((>= size 1024)
+ (format " (%0.2fKB)" (/ size 1024.0))))
+ (cond
+ ((>= speed (* 1024 1024 1024))
+ (format "%0.2f GB/s" (/ speed (* 1024 1024 1024.0))))
+ ((>= speed (* 1024 1024))
+ (format "%0.2f MB/s" (/ speed (* 1024 1024.0))))
+ ((>= speed 1024)
+ (format "%0.2f KB/s" (/ speed 1024.0)))
+ (t
+ (format "%0.2f B/s" speed)))))))
+
+(emchat-do-in-sxemacs
+ (defregexp emchat-curl-filename-regexp (concat emchat-emphasis-url-regexp
+ "/\\([^/].*$\\)")
+ "Regexp matching the file part of a URL."))
+(emchat-do-in-xemacs
+ (defconst emchat-curl-filename-regexp (concat emchat-emphasis-url-regexp
+ "/\\([^/].*$\\)")
+ "Regexp matching the file part of a URL."))
+
+(defun emchat-curl-url (url file directory)
+ "Download URL to FILE in DIRECTORY."
+ (unless (fboundp #'ffi-defun)
+ (error 'emchat-curl))
+ (add-one-shot-hook 'curl:download&-post-hook emchat-curl-hook-function)
+ (curl:download& url (expand-file-name file directory)))
+
+(defun emchat-curl-url-at-point ()
+ "Downloads url at point."
+ (interactive)
+ (when (extentp (extent-at (point)))
+ (let* ((dir (if current-prefix-arg
+ (expand-file-name
+ (read-directory-name "Download directory: "))
+ emchat-curl-download-directory))
+ (url (extent-string (extent-at (point))))
+ (fregexp emchat-curl-filename-regexp)
+ file)
+ (unless (file-directory-p dir)
+ (make-directory-path dir))
+ (setq file
+ (and (string-match fregexp url)
+ (not (string=
+ "/"
+ (substring
+ (substring url (match-beginning 2) (match-end 2)) -1)))
+ (substring url (match-beginning 2) (match-end 2))))
+ (if file
+ (progn
+ (emchat-curl-url url file dir)
+ (setq emchat-curl-file file
+ emchat-curl-dir dir))
+ (message "I don't see a file in: %s" url)))))
+
+(defun emchat-curl-url-at-mouse (event)
+ "Downloads url at event."
+ (interactive "e")
+ (when (extentp (extent-at-event event))
+ (let* ((dir (if current-prefix-arg
+ (expand-file-name
+ (read-directory-name "Download directory: "))
+ emchat-curl-download-directory))
+ (url (extent-string (extent-at-event event)))
+ (fregexp emchat-curl-filename-regexp)
+ file)
+ (unless (file-directory-p dir)
+ (make-directory-path dir))
+ (setq file
+ (and (string-match fregexp url)
+ (not (string=
+ "/"
+ (substring
+ (substring url (match-beginning 2) (match-end 2)) -1)))
+ (substring url (match-beginning 2) (match-end 2))))
+ (if file
+ (progn
+ (emchat-curl-url url file dir)
+ (setq emchat-curl-file file
+ emchat-curl-dir dir))
+ (message-or-box "I don't see a file in: %s" url)))))
+
+(provide 'emchat-curl)
+;;; emchat-curl.el ends here
--- /dev/null
+;; emchat-doctor.el --- Let ICQ users psycho-analize themselves
+
+;; Copyright (C) 2005 - 2007 Steve Youngs
+
+;; Author: Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created: <2005-09-14>
+;; Homepage: http://www.emchat.org/
+;; Keywords: ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+;; Inspired by riece-doctor.el, where much of this was stolen from. :-)
+
+;;; Todo:
+;;
+;;
+
+;;; Code:
+(autoload 'doctor-mode "doctor")
+(autoload 'doctor-read-print "doctor")
+
+(defgroup emchat-doctor nil
+ "Let ICQ users psycho-analyze themselves."
+ :prefix "emchat-"
+ :group 'emchat)
+
+(defcustom emchat-doctor-enabled-flag nil
+ "When non-nil, the doctor is in."
+ :type 'boolean
+ :group 'emchat-doctor)
+
+(defcustom emchat-doctor-begin-string ",,doctor"
+ "When this is received as a msg, start the doctor."
+ :type 'string
+ :group 'emchat-doctor)
+
+(defcustom emchat-doctor-end-string ",,doctor quit"
+ "When this is received as a msg, end the doctor."
+ :type 'string
+ :group 'emchat-doctor)
+
+(defcustom emchat-doctor-hello-string
+ "Hello, I am your therapist.
+To end our session today, just say \",,doctor quit\".
+
+Now, what seems to be the problem, today?"
+ "Initial greeting from the EMchat Doctor."
+ :type 'string
+ :group 'emchat-doctor)
+
+(defcustom emchat-doctor-goodbye-string
+ "Thank you for coming to see me today.
+
+To summarise: basically, you're nuts.
+
+My invoice will arrive in the mail shortly,
+unless you are suffering from a split personality
+disorder, in that case 2 invoices will arrive.
+
+Goodbye, and please don't operate any heavy
+machinery for a while."
+ "String sent when the therapy session ends."
+ :type 'string
+ :group 'emchat-doctor)
+
+;;; Internal variables
+(defvar emchat-doctor-patients nil
+ "List of people who are talking to the doctor.")
+
+(defun emchat-doctor-buffer-name (alias)
+ (concat " *emchat-doctor--" alias "*"))
+
+(defun emchat-doctor-reply (message alias)
+ (emchat-v8-send-simple-message
+ emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias)) message)
+ (emchat-log-outgoing alias ">>> <Doctor>: %s" message))
+
+(defun emchat-doctor (message alias)
+ (if (equal message emchat-doctor-end-string)
+ (progn
+ (setq emchat-doctor-patients (remove alias emchat-doctor-patients))
+ (when (buffer-live-p (emchat-doctor-buffer-name alias))
+ (kill-buffer (emchat-doctor-buffer-name alias)))
+ (emchat-doctor-reply emchat-doctor-goodbye-string alias))
+ (if (equal message emchat-doctor-begin-string)
+ (emchat-doctor-reply "You are already talking to me." alias)
+ (set-buffer (get-buffer-create (emchat-doctor-buffer-name alias)))
+ (doctor-mode)
+ (insert message "\n")
+ (let ((point (point))
+ reply)
+ (doctor-read-print)
+ (setq reply (buffer-substring (1+ point) (- (point) 2)))
+ (emchat-doctor-reply reply alias)))))
+
+(provide 'emchat-doctor)
+;;; emchat-doctor.el ends here
+
--- /dev/null
+;; emchat-emphasis.el --- Gnus-style text emphasis in EMchat
+
+;; Copyright (C) 2005 - 2007 Steve Youngs
+
+;; Author: Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created: <2005-04-29>
+;; Homepage: http://www.emchat.org/
+;; Keywords: ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+;; "prettify" the log buffer, ala Gnus. Most of this is unashamedly
+;; stolen from Gnus.
+
+;;; Todo:
+;;
+;;
+
+;;; Code:
+(eval-when-compile
+ (autoload 'manual-entry "man" nil t))
+
+(defmacro emchat-emphasis-custom-with-format (&rest body)
+ `(let ((format "\
+\\(\\s-\\|^\\|\\=\\|[-\"]\\|\\s(\\)\\(%s\\(\\w+\\(\\s-+\\w+\\)*[.,]?\\)%s\\)\
+\\(\\([-,.;:!?\"]\\|\\s)\\)+\\s-\\|[?!.]\\s-\\|\\s)\\|\\s-\\)"))
+ ,@body))
+
+(defun emchat-emphasis-custom-value-to-external (value)
+ (emchat-emphasis-custom-with-format
+ (if (consp (car value))
+ (list (format format (car (car value)) (cdr (car value)))
+ 2
+ (if (nth 1 value) 2 3)
+ (nth 2 value))
+ value)))
+
+(defun emchat-emphasis-custom-value-to-internal (value)
+ (emchat-emphasis-custom-with-format
+ (let ((regexp (concat "\\`"
+ (format (regexp-quote format)
+ "\\([^()]+\\)" "\\([^()]+\\)")
+ "\\'"))
+ pattern)
+ (if (string-match regexp (setq pattern (car value)))
+ (list (cons (match-string 1 pattern) (match-string 2 pattern))
+ (= (nth 2 value) 2)
+ (nth 3 value))
+ value))))
+
+(defgroup emchat-emphasis nil
+ "Emphasise text in the log buffer."
+ :prefix "emchat-emphasis-"
+ :group 'emchat-log)
+
+(defcustom emchat-emphasis-enabled-flag nil
+ "*When non-nil, emphasise text in the log buffer."
+ :type 'boolean
+ :group 'emchat-emphasis)
+
+(defcustom emchat-emphasis-alist
+ (let ((types
+ '(("\\*" "\\*" bold)
+ ("_" "_" underline)
+ ("/" "/" italic)
+ ("_/" "/_" underline-italic)
+ ("_\\*" "\\*_" underline-bold)
+ ("\\*/" "/\\*" bold-italic)
+ ("_\\*/" "/\\*_" underline-bold-italic))))
+ (nconc
+ (emchat-emphasis-custom-with-format
+ (mapcar (lambda (spec)
+ (list (format format (car spec) (cadr spec))
+ (or (nth 3 spec) 2)
+ (or (nth 4 spec) 3)
+ (intern (format "emchat-emphasis-%s" (nth 2 spec)))))
+ types))
+ '(("\\(\\s-\\|^\\)\\(_\\(\\(\\w\\|_[^_]\\)+\\)_\\)\\(\\s-\\|[?!.,;]\\)"
+ 2 3 emchat-emphasis-underline))))
+ "*Alist that says how to fontify certain phrases.
+Each item looks like this:
+
+ (\"_\\\\(\\\\w+\\\\)_\" 0 1 'underline)
+
+The first element is a regular expression to be matched. The second
+is a number that says what regular expression grouping used to find
+the entire emphasised word. The third is a number that says what
+regexp grouping should be displayed and highlighted. The fourth
+is the face used for highlighting."
+ :type
+ '(repeat
+ (menu-choice
+ :format "%[Customizing Style%]\n%v"
+ :indent 2
+ (group :tag "Default"
+ :value ("" 0 0 default)
+ :value-create
+ (lambda (widget)
+ (let ((value (widget-get
+ (cadr (widget-get (widget-get widget :parent)
+ :args))
+ :value)))
+ (if (not (eq (nth 2 value) 'default))
+ (widget-put
+ widget
+ :value
+ (emchat-emphasis-custom-value-to-external value))))
+ (widget-group-value-create widget))
+ regexp
+ (integer :format "Match group: %v")
+ (integer :format "Emphasise group: %v")
+ face)
+ (group :tag "Simple"
+ :value (("_" . "_") nil default)
+ (cons :format "%v"
+ (regexp :format "Start regexp: %v")
+ (regexp :format "End regexp: %v"))
+ (boolean :format "Show start and end patterns: %[%v%]\n"
+ :on " On " :off " Off ")
+ face)))
+ :get #'(lambda (symbol)
+ (mapcar #'emchat-emphasis-custom-value-to-internal
+ (default-value symbol)))
+ :set #'(lambda (symbol value)
+ (set-default symbol (mapcar #'emchat-emphasis-custom-value-to-external
+ value)))
+ :group 'emchat-emphasis)
+
+(defcustom emchat-emphasise-whitespace-regexp "^[ \t]+\\|[ \t]*\n"
+ "A regexp to describe whitespace which should not be emphasised.
+Typical values are \"^[ \\t]+\\\\|[ \\t]*\\n\" and \"[ \\t]+\\\\|[ \\t]*\\n\".
+The former avoids underlining of leading and trailing whitespace,
+and the latter avoids underlining any whitespace at all."
+ :group 'emchat-emphasis
+ :type 'regexp)
+
+(defcustom emchat-emphasis-url-regexp
+ (concat "\\(https?://\\|s?ftp://\\|gopher://\\|telnet://"
+ "\\|wais://\\|file:/\\|s?news:\\)"
+ "[^]\t\n \"'()<>[^`{}]*[^]\t\n \"'()<>[^`{}.,;]+")
+ "A regular expression matching URLs."
+ :type 'regexp
+ :group 'emchat-emphasis)
+
+(defcustom emchat-emphasis-email-regexp
+ "[-a-zA-Z0-9._]+@\\([-a-zA-z0-9_]+\\.\\)+[a-zA-Z0-9]+"
+ "A regular expression matching email addresses."
+ :type 'regexp
+ :group 'emchat-emphasis)
+
+(defcustom emchat-emphasis-man-regexp "\\b\\w+([1-9n])"
+ "A regular expression matching unix manual pages.
+
+For example, `xemacs\(1\)'."
+ :type 'regexp
+ :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-bold)
+(set-face-parent 'emchat-emphasis-bold 'bold)
+
+(defcustom emchat-emphasis-bold 'emchat-emphasis-bold
+ "Face used for displaying strong emphasised text (*word*)."
+ :type 'face
+ :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-italic)
+(set-face-parent 'emchat-emphasis-italic 'italic)
+
+(defcustom emchat-emphasis-italic 'emchat-emphasis-italic
+ "Face used for displaying italic emphasised text (/word/)."
+ :type 'face
+ :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-underline)
+(set-face-parent 'emchat-emphasis-underline 'underline)
+
+(defcustom emchat-emphasis-underline 'emchat-emphasis-underline
+ "Face used for displaying underlined emphasised text (_word_)."
+ :type 'face
+ :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-underline-bold)
+(set-face-parent 'emchat-emphasis-underline-bold 'bold)
+(set-face-property 'emchat-emphasis-underline-bold 'underline t)
+
+(defcustom emchat-emphasis-underline-bold 'emchat-emphasis-underline-bold
+ "Face used for displaying underlined bold emphasised text (_*word*_)."
+ :type 'face
+ :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-underline-italic)
+(set-face-parent 'emchat-emphasis-underline-italic 'italic)
+(set-face-property 'emchat-emphasis-underline-italic 'underline t)
+
+(defcustom emchat-emphasis-underline-italic 'emchat-emphasis-underline-italic
+ "Face used for displaying underlined italic emphasised text (_/word/_)."
+ :type 'face
+ :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-bold-italic)
+(set-face-parent 'emchat-emphasis-bold-italic 'bold-italic)
+
+(defcustom emchat-emphasis-bold-italic 'emchat-emphasis-bold-italic
+ "Face used for displaying bold italic emphasised text (/*word*/)."
+ :type 'face
+ :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-underline-bold-italic)
+(set-face-parent 'emchat-emphasis-underline-bold-italic 'bold-italic)
+(set-face-property 'emchat-emphasis-underline-bold-italic 'underline t)
+
+(defcustom emchat-emphasis-underline-bold-italic
+ 'emchat-emphasis-underline-bold-italic
+ "Face used for displaying underlined bold italic emphasised text.
+Example: (_/*word*/_)."
+ :type 'face
+ :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-strikethru)
+(set-face-property 'emchat-emphasis-strikethru 'strikethru t)
+
+(defcustom emchat-emphasis-strikethru 'emchat-emphasis-strikethru
+ "Face used for displaying strike-through text (-word-)."
+ :type 'face
+ :group 'emchat-emphasis)
+
+(defface emchat-emphasis-highlight-words
+ '((t (:background "black" :foreground "yellow")))
+ "Face used for displaying highlighted words."
+ :group 'emchat-emphasis)
+
+;;; Internal variables
+
+(defun emchat-emphasis-treat-message (b e)
+ "Emphasise text in region B E according to `emchat-emphasis-alist'."
+ (let ((alist emchat-emphasis-alist)
+ regexp elem beg invisible visible face)
+ (save-excursion
+ (save-restriction
+ (narrow-to-region b e)
+ (goto-char (point-min))
+ (setq beg (point))
+ (while (setq elem (pop alist))
+ (goto-char beg)
+ (setq regexp (car elem)
+ invisible (nth 1 elem)
+ visible (nth 2 elem)
+ face (nth 3 elem))
+ (while (re-search-forward regexp nil t)
+ (when (and (match-beginning visible) (match-beginning invisible))
+ (put-text-property
+ (match-beginning invisible) (match-end invisible) 'invisible t)
+ (remove-text-properties
+ (match-beginning visible) (match-end visible) '(invisible t))
+ (put-text-property
+ (match-beginning visible) (match-end visible) 'face face)
+ (goto-char (match-end invisible)))))))))
+
+(defun emchat-emphasis-visit-hyperlink-at-point ()
+ "Follow the hyperlink at point in the EMchat log buffer.
+
+This can either be a URL, in which case `browse-url' is called with
+the string of the extent as an arg. Or it can be an email address, in
+which case `compose-mail' is called. Or it can be a Unix manual page,
+where `manual-entry' is called."
+ (interactive)
+ (when (extentp (extent-at (point)))
+ (let ((str (extent-string (extent-at (point)))))
+ (cond ((string-match emchat-emphasis-url-regexp str)
+ (browse-url str))
+ ((string-match emchat-emphasis-email-regexp str)
+ (compose-mail str))
+ ((string-match emchat-emphasis-man-regexp str)
+ (if (fboundp 'manual-entry)
+ (manual-entry str)
+ (error 'unimplemented "Unix manual pages")))
+ (t
+ (error 'invalid-operation))))))
+
+(defun emchat-emphasis-visit-hyperlink-at-mouse (event)
+ "Follow the hyperlink at EVENT in the EMchat log buffer.
+
+This can either be a URL, in which case `browse-url' is called with
+the string of the extent as an arg. Or it can be an email address, in
+which case `compose-mail' is called. Or it can be a Unix manual page,
+where `manual-entry' is called."
+ (interactive "e")
+ (when (extentp (extent-at-event event))
+ (let ((str (extent-string (extent-at-event event))))
+ (cond ((string-match emchat-emphasis-url-regexp str)
+ (browse-url str))
+ ((string-match emchat-emphasis-email-regexp str)
+ (compose-mail str))
+ ((string-match emchat-emphasis-man-regexp str)
+ (if (fboundp 'manual-entry)
+ (manual-entry str)
+ (error 'unimplemented "Unix manual pages")))
+ (t
+ (error 'invalid-operation))))))
+
+(defun emchat-emphasis-hyperlink-message (b e)
+ "Add hyperlinks to the message in region B E.
+
+In other words, URLs, email addresses, and unix manual page names will
+be \"clickable\"."
+ (save-excursion
+ (save-restriction
+ (narrow-to-region b e)
+ (goto-char (point-min))
+ (while (re-search-forward emchat-emphasis-url-regexp nil t)
+ (let ((extent (make-extent (match-beginning 0) (match-end 0)))
+ (echo "Mouse button2 -- Follow this link."))
+ (set-extent-property extent 'face 'widget-button-face)
+ (set-extent-property extent 'mouse-face 'highlight)
+ (set-extent-property extent 'keymap emchat-hyperlink-map)
+ (set-extent-property extent 'help-echo echo)
+ (set-extent-property extent 'balloon-help echo)
+ (set-extent-property extent 'duplicable t)))
+ (while (re-search-forward emchat-emphasis-email-regexp nil t)
+ (let ((extent (make-extent (match-beginning 0) (match-end 0)))
+ (echo "Mouse button2 -- Compose mail."))
+ (set-extent-property extent 'face 'emchat-emphasis-highlight-words)
+ (set-extent-property extent 'mouse-face 'highlight)
+ (set-extent-property extent 'keymap emchat-hyperlink-map)
+ (set-extent-property extent 'help-echo echo)
+ (set-extent-property extent 'balloon-help echo)
+ (set-extent-property extent 'duplicable t)))
+ (while (re-search-forward emchat-emphasis-man-regexp nil t)
+ (let ((extent (make-extent (match-beginning 0) (match-end 0)))
+ (echo "Mouse button2 -- Read this manual."))
+ (set-extent-property extent 'face 'man-xref)
+ (set-extent-property extent 'mouse-face 'highlight)
+ (set-extent-property extent 'keymap emchat-hyperlink-map)
+ (set-extent-property extent 'help-echo echo)
+ (set-extent-property extent 'balloon-help echo)
+ (set-extent-property extent 'duplicable t))))))
+
+(provide 'emchat-emphasis)
+;;; emchat-emphasis.el ends here
+
--- /dev/null
+;;; emchat-history.el --- Mode for viewing history in EMchat and its interface.
+
+;; Copyright (C) 2005 - 2007 Steve Youngs, Alexey Mikhailov
+
+;; Author: Alexey Mikhailov <karma@sxemacs.org>
+;; Maintainer: Alexey Mikhailov <karma@sxemacs.org>
+;; Created: 2005-04-19
+;; Homepage: http://www.emchat.org/
+;; Keywords: comm ICQ history
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+;; Provides mode for viewing person history and interface for EMchat.
+;; To start using it, add this to your ~/.sxemacs/init.el...
+;;
+;; (setq emchat-history-enabled-flag t)
+
+(eval-and-compile
+ (require 'outline)
+ (require 'emchat)
+ (require 'emchat-log)
+ (require 'font-lock))
+
+(defvar emchat-history-old-window-config nil)
+
+(defun emchat-history (&optional alias)
+ "Show history log for ALIAS person."
+ (interactive)
+ (let* ((alias (or alias
+ (emchat-completing-read "Show history for: "
+ emchat-all-aliases nil t)))
+ (histf (emchat-world-getf alias 'history)))
+ (when histf
+ (find-file histf)
+ (emchat-history-mode))))
+
+(defun emchat-history-around ()
+ "Show history around."
+ (interactive)
+ (emchat-history (emchat-alias-around)))
+
+
+(defun emchat-history-here-other-window (&optional count)
+ "Show history around in other window."
+ (interactive)
+ (setq emchat-history-old-window-config (current-window-configuration))
+ (unless count (setq count 1))
+ (let ((alias (emchat-alias-here)))
+ (other-window count)
+ (emchat-history alias)))
+
+(defvar emchat-history-outline-regexp "\\(^\\s-?[0-9]*[ ][A-Za-z]*[ ][A-Z]..\:..\\)"
+ "Regexp for history header.
+See `outline-regexp'.")
+
+(defvar emchat-history-event-regexp
+ (concat "\\(^\\s-?[0-9]*[ ][A-Za-z]*[ ][A-Z]..\:..\\)"
+ ".\\(\\[[A-Za-z0-9].*\\]\\).\\([\*><]*\\).\\(.*\\)")
+ "Regexp for history event.
+
+First paren set matches date header, second -- person nickname, third
+-- event type, fourth -- all other stuff.")
+
+(defun emchat-history-mode ()
+ "Major mode for viewing history in emchat.
+Commands: \\{emchat-history-mode-map}
+
+Turning on `emchat-history-mode' runs the hook `emchat-history-mode-hook'."
+ (interactive)
+ (kill-all-local-variables)
+ (use-local-map emchat-history-mode-map)
+ (setq mode-name "emchat-history")
+ (setq major-mode 'emchat-history-mode)
+ (easy-menu-add emchat-history-menu)
+ (font-lock-mode t)
+ (toggle-read-only t)
+ (outline-minor-mode t)
+ (set (make-local-variable 'outline-regexp)
+ emchat-history-outline-regexp)
+ (goto-char (point-max))
+ (forward-line -1)
+ (run-hooks 'emchat-history-mode-hook))
+
+(defun emchat-history-bury-buffer (&optional kill)
+ "Bury buffer in `emchat-history' mode.
+
+With optional prefix arg, KILL, kill the buffer instead of burying
+it."
+ (interactive "P")
+ ;; safeguard against calling this when the current buffer isn't in
+ ;; emchat-history-mode
+ (when (eq major-mode 'emchat-history-mode)
+ (if current-prefix-arg
+ (kill-buffer nil)
+ (bury-buffer nil)))
+ ;; Possibly restore the old window config
+ (when emchat-history-old-window-config
+ (set-window-configuration emchat-history-old-window-config)
+ (setq emchat-history-old-window-config nil)))
+
+(defun emchat-history-save (&optional alias)
+ "Save all the open history files."
+ (interactive)
+ (if alias
+ (with-current-buffer (find-buffer-visiting
+ (emchat-world-getf alias 'history))
+ (save-buffer))
+ (mapcar
+ #'(lambda (a)
+ (let ((buf (find-buffer-visiting
+ (emchat-world-getf a 'history))))
+ (and buf
+ (with-current-buffer buf
+ (save-buffer)))))
+ emchat-all-aliases)))
+
+(defalias 'emchat-history-next 'outline-forward-same-level)
+(defalias 'emchat-history-prev 'outline-backward-same-level)
+
+(defface emchat-history-timestamp-face
+ '((((background light))
+ (:foreground "red4" :bold t)))
+ "Face used to highlight timestamps in `emchat-history' mode."
+ :group 'emchat-log)
+
+(defface emchat-history-event-type-face
+ '((((background light))
+ (:foreground "magenta3" :bold t)))
+ "Face used to highlight event types in `emchat-history' mode."
+ :group 'emchat-log)
+
+(defface emchat-history-nick-face
+ '((((background light))
+ (:foreground "green4" :bold t)))
+ "Face used to highlight nicks in `emchat-history' mode."
+ :group 'emchat-log)
+
+(defconst emchat-history-font-lock-keywords
+ (list
+ (cons emchat-history-event-regexp '(1 'emchat-history-timestamp-face))
+ (cons emchat-history-event-regexp '(2 'emchat-history-nick-face))
+ (cons emchat-history-event-regexp '(3 'emchat-history-event-type-face)))
+ "Highlighting rules for `emchat-history' buffers.")
+
+(provide 'emchat-history)
+
+;;; emchat-history.el ends here
--- /dev/null
+;;; emchat-log.el --- Logging code for EMchat.
+
+;; Copyright (C) 2002 - 2007 Steve Youngs
+
+;; Author: Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created: 2002-10-01
+;; Homepage: http://www.emchat.org/
+;; Keywords: comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+;; Logs incoming and outgoing events in EMchat.
+
+(eval-and-compile
+ (defvar emchat-directory nil)
+ (require 'emchat-emphasis)
+ (require 'emchat-curl)
+ (require 'emchat-menu)
+ (require 'emchat-track)
+ (require 'outline))
+
+(eval-when-compile
+ (defvar emchat-history-enabled-flag nil)
+ (defvar emchat-history-directory)
+ (autoload #'smiley-region "smiley" nil t))
+
+(defgroup emchat-log nil
+ "Message logging preferences."
+ :group 'emchat)
+
+(defcustom emchat-log-fill-column 0
+ "Fill column for `emchat-log-buffer'.
+
+If this is set to 0 \(zero\), the default, the fill-column in the log
+buffer is left alone. In other words, default value for fill-column."
+ :type 'integer
+ :group 'emchat-log)
+
+(defcustom emchat-log-filename (expand-file-name "log" emchat-directory)
+ "*Pathname and filename for storing emchat log.
+Automatically created if the directory is non-existent."
+ :type 'file
+ :group 'emchat-log)
+
+(defcustom emchat-log-buffer-position-flag 'tail
+ "*Non-nil means automatically updating buffer position.
+Nil means no automatic update, 'tail means keeping the bottom of the buffer
+visible, other non-nil means keeping the top of the buffer visible."
+ :group 'emchat-log
+ :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-info-flag 'tail
+ "*Non-nil means log misc info.
+These include any info from ICQ server other than buddy messages, status
+change notice, and query results.
+Nil means no log, 'tail means putting new log at the end of the log
+buffer, other non-nil means putting new log at the beginning."
+ :group 'emchat-log
+ :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-buddy-status-flag 'tail
+ "*Non-nil means log buddy status change notice.
+Nil means no log, 'tail means putting new log at the end of the log
+buffer, other non-nil means putting new log at the beginning."
+ :group 'emchat-log
+ :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-buddy-message-flag 'tail
+ "*Non-nil means log buddy messages from ICQ server.
+Nil means no log, 'tail means putting new log at the end of the log
+buffer, other non-nil means putting new log at the beginning."
+ :group 'emchat-log
+ :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-outgoing-flag 'tail
+ "*Non-nil means log outgoing messages to ICQ server.
+Nil means no log, 'tail means putting new log at the end of the log
+buffer, other non-nil means putting new log at the beginning."
+ :group 'emchat-log
+ :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-error-flag 'tail
+ "*Non-nil means log critical error messages.
+Nil means no log, 'tail means putting new log at the end of the log
+buffer, other non-nil means putting new log at the beginning."
+ :group 'emchat-log
+ :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-debug-flag nil
+ "*Non-nil means log verbose debugging messages.
+Nil means no log, 'tail means putting new log at the end of the log
+buffer, other non-nil means putting new log at the beginning."
+ :group 'emchat-log
+ :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-system-flag 'tail
+ "*Non-nil means log system messages.
+These include network status, login status, and others.
+Nil means no log, 'tail means putting new log at the end of the log
+buffer, other non-nil means putting new log at the beginning."
+ :group 'emchat-log
+ :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-info-mark nil
+ "*Non-nil means mark unread.
+These include any info from ICQ server other than buddy messages,
+status change notice, and query results.
+Nil means mark read."
+ :group 'emchat-log
+ :type 'boolean)
+
+(defcustom emchat-log-buddy-status-mark nil
+ "*Non-nil means mark buddy status change notice unread.
+Nil means mark read."
+ :type 'boolean
+ :group 'emchat-log)
+
+(defcustom emchat-log-buddy-message-mark t
+ "*Non-nil means mark buddy messages unread.
+Nil means mark read."
+ :type 'boolean
+ :group 'emchat-log)
+
+(defcustom emchat-log-outgoing-mark nil
+ "*Non-nil means mark outgoing messages unread.
+Nil means mark read."
+ :group 'emchat-log
+ :type 'boolean)
+
+(defcustom emchat-log-error-mark t
+ "*Non-nil means mark critical error messages unread.
+Nil means mark read."
+ :group 'emchat-log
+ :type 'boolean)
+
+(defcustom emchat-log-debug-mark t
+ "*Non-nil means mark verbose debugging messages unread.
+Nil means mark read."
+ :group 'emchat-log
+ :type 'boolean)
+
+(defcustom emchat-log-system-mark nil
+ "*Non-nil means mark system messages unread.
+Nil means mark read."
+ :group 'emchat-log
+ :type 'boolean)
+
+(defcustom emchat-save-log-on-exit-p t
+ "*Non-nil means the log file will be automatically saved when exiting."
+ :group 'emchat-log
+ :type 'boolean
+ :tag "Save log on exit")
+
+(defcustom emchat-smiley nil
+ "*Non-nil means smileys are enabled."
+ :group 'emchat-interface
+ :type '(choice (item t) (item nil)))
+
+;;; Internal variables
+
+(defvar emchat-log-buffer nil
+ "Buffer for log.")
+
+(defvar emchat-log-outline-regexp "^...:.. "
+ "Regexp for log header.
+See `outline-regexp'.")
+
+(defvar emchat-log-mode-syntax-table
+ (let ((table (copy-syntax-table text-mode-syntax-table)))
+ (modify-syntax-entry ?~ "w " table)
+ (modify-syntax-entry ?` "w " table)
+ (modify-syntax-entry ?! "w " table)
+ (modify-syntax-entry ?@ "w " table)
+ (modify-syntax-entry ?# "w " table)
+ (modify-syntax-entry ?$ "w " table)
+ (modify-syntax-entry ?% "w " table)
+ (modify-syntax-entry ?^ "w " table)
+ (modify-syntax-entry ?& "w " table)
+ (modify-syntax-entry ?( "w " table)
+ (modify-syntax-entry ?) "w " table)
+ (modify-syntax-entry ?- "w " table)
+ (modify-syntax-entry ?+ "w " table)
+ (modify-syntax-entry ?= "w " table)
+ (modify-syntax-entry ?{ "w " table)
+ (modify-syntax-entry ?[ "w " table)
+ (modify-syntax-entry ?} "w " table)
+ (modify-syntax-entry ?] "w " table)
+ (modify-syntax-entry ?\\ "w " table)
+ (modify-syntax-entry ?| "w " table)
+ (modify-syntax-entry ?: "w " table)
+ (modify-syntax-entry ?\; "w " table)
+ (modify-syntax-entry ?\" "w " table)
+ (modify-syntax-entry ?' "w " table)
+ (modify-syntax-entry ?< "w " table)
+ (modify-syntax-entry ?, "w " table)
+ (modify-syntax-entry ?> "w " table)
+ (modify-syntax-entry ?. "w " table)
+ (modify-syntax-entry ?\? "w " table)
+ table)
+ "Syntax table used while in `emchat-log-mode'.")
+
+(defun emchat-log-update-modeline ()
+ (let ((invisible emchat-user-meta-invisible))
+ (if invisible
+ (setq modeline-buffer-identification
+ (list (cons modeline-buffer-id-left-extent
+ (cons 10 (list "[" 'emchat-user-alias "]: ")))
+ (cons modeline-buffer-id-right-extent
+ (cons 1 (list "<"
+ 'emchat-user-status
+ 'emchat-user-meta-invisibility-indicator
+ ">")))))
+ (setq modeline-buffer-identification
+ (list (cons modeline-buffer-id-left-extent
+ (cons 10 (list "[" 'emchat-user-alias "]: ")))
+ (cons modeline-buffer-id-right-extent
+ (cons 1 (list "<"
+ 'emchat-user-status
+ ">"))))))))
+
+(defun emchat-log-mode ()
+ "Major mode for logging messages in emchat.
+Commands: \\{emchat-log-mode-map}
+
+Turning on `emchat-log-mode' runs the hook `emchat-log-mode-hook'."
+ (interactive)
+ (kill-all-local-variables)
+ (use-local-map emchat-log-mode-map)
+ (setq mode-name "emchat-log")
+ (setq major-mode 'emchat-log-mode)
+ ;; put easy-menu-add after set mode-name
+ (easy-menu-add emchat-main-easymenu)
+ (easy-menu-add emchat-buddy-menu)
+ (easy-menu-add emchat-log-menu)
+ (unless (zerop emchat-log-fill-column)
+ (setq fill-column emchat-log-fill-column))
+ ;; No menubar from outline mode.
+ (let ((features (remove 'menubar features)))
+ (outline-minor-mode))
+ (set (make-local-variable 'outline-regexp)
+ emchat-log-outline-regexp)
+ (emchat-log-update-modeline)
+ ;; Use our syntax-table
+ (set-syntax-table emchat-log-mode-syntax-table)
+ (run-hooks 'emchat-log-mode-hook))
+
+(defvar emchat-log-logo (expand-file-name "logo.png" emchat-glyph-dir)
+ "The logo used at the top of a new log buffer.")
+
+(defvar emchat-log-header (expand-file-name "log-header.xbm"
+ emchat-glyph-dir)
+ "The intro at the top of a new log buffer.")
+
+;;;###autoload
+(defun emchat-log-show-buffer (&optional new no-select)
+ "Switch to `emchat-log-buffer'.
+Create buffer with log file if buffer does not exists already.
+Non-nil NEW means rotate and create a new log file.
+Non-nil NO-SELECT means don't select log window.
+See `emchat-log-filename'."
+ (interactive)
+ (when new
+ ;; save and close current log first if any
+ (setq emchat-log-buffer
+ (find-buffer-visiting emchat-log-filename))
+
+ (if emchat-log-buffer
+ (with-current-buffer emchat-log-buffer
+ (save-buffer)
+ (kill-buffer nil)))
+
+ ;; rename old log in disk
+ (if (file-exists-p emchat-log-filename)
+ (rename-file
+ emchat-log-filename
+ (concat emchat-log-filename
+ ;; in case you do something stupid with it
+ (format-time-string "-%Y-%b%d-%H%M-%S")))))
+
+ (unless (buffer-live-p emchat-log-buffer)
+ (setq emchat-log-buffer (find-file-noselect emchat-log-filename))
+ (with-current-buffer emchat-log-buffer
+ (emchat-log-mode)
+ (when (zerop (buffer-size))
+ (if (and (device-on-window-system-p)
+ (featurep '(and png xbm)))
+ (progn
+ (insert "\n")
+ (let ((ext (make-extent (point) (point))))
+ (set-extent-begin-glyph
+ ext
+ (make-glyph (list (vector 'png ':file emchat-log-logo))))
+ (set-extent-end-glyph
+ ext
+ (make-glyph (list (vector 'xbm ':file emchat-log-header))))
+ (insert "\n\n")))
+ (insert "===========================================\n"
+ "Welcome to EMchat - The (S)XEmacs IM Client\n\n"
+ "If you like this software, please consider\n"
+ " \'M-x emchat-donation RET\'\n"
+ "===========================================\n\n")))))
+ (unless no-select
+ (switch-to-buffer emchat-log-buffer)))
+
+(defun emchat-log-new-file ()
+ "Rotate and create a new log file."
+ (interactive)
+ (emchat-log-show-buffer 'new))
+
+(defconst emchat-log-entry-re "^[SMTWRFA][0-9][0-9]:[0-9][0-9]"
+ "Regular expression matching the beginning of a log entry.")
+
+(defun emchat-log-update-history (id message weekday)
+ "Updates the history for ID, with MESSAGE.
+
+WEEKDAY is an array of 7 characters indicating a day of the week for
+the timestamp."
+ (when (and (member id emchat-visible-contacts)
+ (not (member id emchat-invisible-contacts))
+ (not (search "***|" message)))
+ (let ((hfile (emchat-world-getf id 'history)))
+ (save-excursion
+ (with-current-buffer (find-file-noselect hfile 'nowarn)
+ (when buffer-read-only
+ (toggle-read-only))
+ (goto-char (point-max))
+ (insert
+ (format-time-string "%e %b ")
+ (aref weekday (string-to-number (format-time-string "%w")))
+ (format-time-string "%R ")
+ (format "[%s] %s" id message))
+ (let ((beg (point-at-bol)))
+ (fill-region beg (point-max))))))))
+
+(defun emchat-log-update-tracker (id message)
+ "Update the EMchat track modeline indicator.
+
+ID is the entity that sent MESSAGE."
+ (unless (get 'emchat-track 'initialized)
+ (emchat-track-init))
+ (and (not (get-buffer-window emchat-log-buffer))
+ (ecase emchat-track-events-type
+ (all (emchat-track-add-nick id))
+ (incoming
+ (and (not (search ">>>" message)) ; XXX
+ (not (search "***|" message)) ; XXX
+ (emchat-track-add-nick id)))
+ (msg
+ (and (not (equal id "!debug")) ; XXX
+ (not (equal id "!error")) ; XXX
+ (not (equal id "!system")) ; XXX
+ (not (search ">>>" message)) ; XXX
+ (not (search "***|" message)) ; XXX
+ (emchat-track-add-nick id))))))
+
+(defun emchat-log-update-balloon (id)
+ "Update the balloon-help extent property for ID."
+ (save-excursion
+ (search-backward id)
+ (let* ((exp (extent-at (point)))
+ (bhelp
+ (format
+ "%s (%s)\n Status: %s\n Groups: %s\nHistory: %s\n\n\n"
+ id
+ (emchat-alias-uin id)
+ (or (emchat-world-getf id 'status)
+ "offline")
+ (or (emchat-world-getf id 'group)
+ "none")
+ (or (emchat-world-getf id 'history)
+ "none")))
+ (face (emchat-status-face (emchat-world-getf id 'status))))
+ (when (extentp exp)
+ (set-extent-property exp 'face face)
+ (set-extent-property exp 'balloon-help bhelp)))))
+
+(defun emchat-log (id message option mark-unread)
+ "Log message under ID.
+Put MESSAGE at the end of log buffer if OPTION is non-nil.
+Mark MESSAGE unread if MARK-UNREAD is non-nil"
+ (if (and option (buffer-live-p emchat-log-buffer))
+ (with-current-buffer emchat-log-buffer
+ (save-excursion
+ (let ((start-point (if (eq option 'tail)
+ (point-max) (point-min)))
+ (weekday ["S" "M" "T" "W" "R" "F" "A"])
+ ;; to fill messages correctly
+ (paragraph-start ""))
+ (goto-char start-point)
+ (insert
+ (aref weekday (string-to-number (format-time-string "%w")))
+ (format-time-string "%R ")
+ ;; use concat instead of format for extent
+ (concat "[" id "] " message "\n"))
+ (fill-region start-point (point))
+ (when emchat-history-enabled-flag
+ (emchat-log-update-history id message weekday))
+ (when emchat-track-enable
+ (emchat-log-update-tracker id message))
+ (when (member id emchat-all-aliases)
+ (emchat-log-update-balloon id))
+ (when emchat-smiley
+ (smiley-region start-point (point)))
+ (when emchat-emphasis-enabled-flag
+ (emchat-emphasis-treat-message start-point (point)))
+ (emchat-emphasis-hyperlink-message start-point (point))
+ (goto-char start-point)
+ (if mark-unread
+ (emchat-log-mark-unread)
+ (emchat-log-mark-read))))
+ (if emchat-log-buffer-position-flag
+ (if (eq emchat-log-buffer-position-flag 'tail)
+ (progn
+ (goto-char (point-max))
+ (re-search-backward emchat-log-entry-re))
+ (progn
+ (goto-char (point-min))
+ (re-search-forward emchat-log-entry-re)))))))
+
+(defun emchat-log-info (&rest messages)
+ "See `emchat-log-info-flag'.
+MESSAGES is an argument list for `format' to be inserted."
+ (emchat-log "!info" (apply 'format messages) emchat-log-info-flag emchat-log-info-mark))
+
+(defun emchat-log-buddy-status (alias &rest messages)
+ "See `emchat-log-buddy-status-flag'.
+ALIAS is an id to be logged under.
+MESSAGES is an argument list for `format' to be inserted."
+ (emchat-log alias
+ (apply 'format messages)
+ emchat-log-buddy-status-flag emchat-log-buddy-status-mark))
+
+(defun emchat-log-buddy-message (alias fmt &rest fmt-messages)
+ "See `emchat-log-buddy-message-flag'.
+ALIAS is an id to be logged under.
+FMT is message format, passed directly to `format'.
+FMT-MESSAGES are arguments for `format'."
+ (emchat-log alias
+ (apply 'format fmt fmt-messages)
+ emchat-log-buddy-message-flag emchat-log-buddy-message-mark))
+
+(defun emchat-log-buddy-url (alias message url)
+ "See `emchat-log-buddy-message-flag'.
+ALIAS is an id MESSAGE to be logged under.
+URL will be highlighted."
+ ;; idea from Erik Arneson <erik@starseed.com>
+ (set-extent-properties
+ (make-extent 0 (length url) url)
+ `(highlight t duplicable t
+ keymap ,emchat-hyperlink-map
+ balloon-help "Mouse button2 -- Follow this link."
+ face ,widget-button-face))
+ (emchat-log alias (concat message "\nURL: " url)
+ emchat-log-buddy-message-flag emchat-log-buddy-message-mark))
+
+(defun emchat-log-outgoing (alias &rest messages)
+ "See `emchat-log-outgoing-flag'.
+ALIAS is an id to be logged under.
+MESSAGES is an argument list for `format' to be inserted."
+ (emchat-log alias
+ (apply 'format messages) emchat-log-outgoing-flag emchat-log-outgoing-mark))
+
+(defun emchat-log-error (&rest messages)
+ "See `emchat-log-error-flag'.
+MESSAGES is an argument list for `format' to be inserted."
+ (emchat-log "!error"
+ (apply 'format messages) emchat-log-error-flag emchat-log-error-mark))
+
+(defun emchat-log-debug (&rest messages)
+ "See `emchat-log-debug-flag'.
+MESSAGES is an argument list for `format' to be inserted."
+ (emchat-log "!debug"
+ (apply 'format messages) emchat-log-debug-flag emchat-log-debug-mark))
+
+(defun emchat-log-system (&rest messages)
+ "See `emchat-log-system-flag'.
+MESSAGES is an argument list for `format' to be inserted."
+ (emchat-log "!system"
+ (apply 'format messages) emchat-log-system-flag emchat-log-system-mark)
+ (run-hooks 'emchat-system-message-hook))
+
+(defface emchat-face-log-unread
+ '((((background dark))
+ (:foreground "red"))
+ (((background light))
+ (:foreground "red4" :bold t)))
+ "Face for unread log messages."
+ :group 'emchat-log)
+
+(defface emchat-face-log-read
+ '((((background dark))
+ (:foreground "turquoise"))
+ (((background light))
+ (:foreground "steelblue")))
+ "Face for read log messages."
+ :group 'emchat-log)
+
+(defvar emchat-log-mark-alist
+ '((unread . emchat-face-log-unread)
+ (read . emchat-face-log-read))
+ "Alist of log message marks and their colors.")
+
+(defun emchat-log-mark (&optional mark)
+ "Mark log message around point using MARK.
+Possible MARK: 'read, 'unread, 'toggle.
+Nil MARK means 'read.
+See `emchat-face-log-unread' and `emchat-face-log-read'."
+ (save-excursion
+ ;; so that we can mark current line even at bol
+ (end-of-line)
+ (let ((len (length emchat-log-outline-regexp))
+ (p (search-backward-regexp emchat-log-outline-regexp nil t))
+ (face (cdr (assoc mark emchat-log-mark-alist))))
+ (if p (add-text-properties
+ p (+ len p -2)
+ (list 'face face 'start-open t))))))
+
+(defun emchat-log-mark-region (start end &optional mark)
+ "Mark all log messages in the region.
+MARK is any mark in `emchat-log-mark'."
+ (interactive "r")
+ (save-excursion
+ (goto-char start)
+ ;; Due to bad design of outline.el, we use condition-case to guard
+ ;; against error when advancing at the end of buffer.
+ (condition-case nil
+ (while (<= (point) end)
+ (emchat-log-mark mark)
+ (emchat-log-next 1))
+ (error nil))))
+
+(defun emchat-log-mark-unread (&optional mark-region)
+ "Mark log message around point as unread.
+Non-nil MARK-REGION or prefix argument means marks all log in the region."
+ (interactive "P")
+ (if mark-region
+ (emchat-log-mark-region (region-beginning) (region-end) 'unread)
+ (emchat-log-mark 'unread)))
+
+(defun emchat-log-mark-read (&optional mark-region)
+ "Mark log message around point as read.
+Non-nil MARK-REGION or prefix argument means marks all log in the region."
+ (interactive "P")
+ (if mark-region
+ (emchat-log-mark-region (region-beginning) (region-end) 'read)
+ (emchat-log-mark 'read))
+ (if (interactive-p)
+ (run-hooks 'emchat-read-message-hook)))
+
+(defun emchat-log-around ()
+ "Return the log message around.
+If called interactively, display and push log into `kill-ring'."
+ (interactive)
+ (let* ((log-start (save-excursion
+ (outline-back-to-heading)
+ (search-forward "] " nil t)
+ (point)))
+ (log-end (or (save-excursion
+ (condition-case nil
+ (outline-get-next-sibling)
+ (error nil)))
+ (point-max)))
+ (log (buffer-substring log-start log-end)))
+ (when (interactive-p)
+ (message log)
+ (kill-new log))
+ log))
+
+(defalias 'emchat-log-contract 'hide-subtree)
+(defalias 'emchat-log-expand 'show-subtree)
+(defalias 'emchat-log-previous 'outline-backward-same-level)
+(defalias 'emchat-log-next 'outline-forward-same-level)
+
+(defun emchat-log-next-unread ()
+ "Moves point to the next unread message.
+Does nothing if there are no unread messages after point."
+ (interactive)
+ (let ((here (point)))
+ (goto-char
+ (catch 'where
+ (progn
+ (while (not (eq here (point-max))) ; mildly bogus target
+ (let ((next (next-single-property-change here 'face)))
+ (unless next
+ (throw 'where (point)))
+ (if (eq (get-text-property next 'face)
+ (cdr (assoc 'unread emchat-log-mark-alist)))
+ (throw 'where next)
+ (setq here next)))))))))
+
+(defun emchat-log-previous-unread ()
+ "Moves point to the previous unread message.
+Does nothing if there are no unread messages after point."
+ (interactive)
+ (let ((here (point)))
+ (goto-char
+ (catch 'where
+ (progn
+ (while (not (eq here (point-max))) ; mildly bogus target
+ (let ((prev (previous-single-property-change here 'face)))
+ (unless prev
+ (throw 'where (point)))
+ (if (eq (get-text-property prev 'face)
+ (cdr (assoc 'unread emchat-log-mark-alist)))
+ (throw 'where prev)
+ (setq here prev)))))))))
+
+(provide 'emchat-log)
+
+;;; emchat-log.el ends here
+
--- /dev/null
+;;; emchat-menu.el --- Menus and keymaps for EMchat.
+
+;; Copyright (C) 2002 - 2007 Steve Youngs
+
+;; Author: Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created: 2002-10-01
+;; Homepage: http://www.emchat.org/
+;; Keywords: comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Code
+(eval-when-compile
+ (require 'emchat-utils))
+
+;; Global bindings.
+
+;; Define new prefix for EMchat
+(define-prefix-command 'emchat-prefix)
+
+;; Set EMchat global bindings
+(define-key emchat-prefix "Xi" #'emchat-login)
+(define-key emchat-prefix "w" #'emchat-show-window)
+(define-key emchat-prefix "f" #'world-find)
+
+;; Bindings common to both log and buddy buffer.
+(defvar emchat-main-map
+ (let ((map (make-keymap 'emchat-main-map)))
+ (suppress-keymap map)
+ (define-key map [X] nil) ; BUG?
+ (define-key map [X i] #'emchat-login)
+ (define-key map [X o] #'emchat-logout)
+ (define-key map [X q] #'emchat-exit)
+ (define-key map [X s] #'emchat-change-status)
+ (define-key map [b] #'emchat-toggle-invisibility)
+ (define-key map [S] #'emchat-group-select-aliases)
+ (define-key map [s] #'emchat-group-select-aliases)
+ (define-key map [w] #'emchat-show-window)
+ (define-key map [H] #'emchat-history-save)
+ (define-key map [h] #'emchat-hide-window)
+ (define-key map [M] #'emchat-send-message)
+ (define-key map [m] #'emchat-send-message)
+ (define-key map [U] #'emchat-send-url)
+ (define-key map [u] #'emchat-send-url)
+ (define-key map [A] #'emchat-authorize)
+ (define-key map [a] #'emchat-authorize)
+ (define-key map [i] #'emchat-query-info)
+ (define-key map [I] #'emchat-query-info)
+ (define-key map [F] #'emchat-search)
+ (define-key map [f] #'world-find)
+ (define-key map [V] nil)
+ (define-key map [V c] #'emchat-buddy-view-connected)
+ (define-key map [V v] #'emchat-buddy-view-active)
+ (define-key map [V a] #'emchat-buddy-view-all)
+ map)
+ "Keyboard map common for `emchat-log-mode-map' and `emchat-buddy-mode-map'.")
+
+(defvar emchat-main-menu
+ '("EMchat"
+ ["Show Window" emchat-show-window t]
+ ["Hide Window" emchat-hide-window t]
+ ["Register New UIN" emchat-register-new-user t]
+ ["Change Password" emchat-change-password t]
+ ["Login" emchat-login t]
+ ["Logout" emchat-logout t]
+ ["Exit" emchat-exit t]
+ "---"
+ ["Select" emchat-group-select-aliases t]
+ ["Send Message" emchat-send-message t]
+ ["Send URL" emchat-send-url t]
+ ["Authorize" emchat-authorize t]
+ ["Change Status" emchat-change-status t]
+ ["Change Idle Timeout" emchat-change-idle-timeout t]
+ ["Search" emchat-search t]
+ ["Update Meta Info" emchat-update-meta-info t]
+ "---"
+ ["alias -> uin" emchat-alias-uin t]
+ ["uin -> alias" emchat-uin-alias t]
+ ["Redo Packet" emchat-redo-hex t]
+ ["Resend Contact List" emchat-send-contact-list t]
+ ["Buddy Buffer" emchat-buddy-show-buffer t]
+ ["Log Buffer" emchat-log-show-buffer t]
+ "---"
+ ["Email Author" emchat-email-author t]
+ ["Submit Bug Report" (emchat-report-bug emchat-blurb) t]
+ ["Make a Donation" emchat-donation t]
+ ["Customize" emchat-customize t])
+ "Menu for both `emchat-log-mode' and `emchat-buddy-mode'.")
+
+(easy-menu-define
+ emchat-main-easymenu nil "EMchat" emchat-main-menu)
+
+(defvar emchat-log-menu
+ '("EMchat-log"
+ ["Select Around" emchat-select-alias-around t]
+ ["Send Message Around" emchat-send-message-alias-around t]
+ ["Send URL Around" emchat-send-url-alias-around t]
+ ["Forward Message" emchat-forward-message-around t]
+ ["Oops!" emchat-oops t]
+ ["Authorize Around" emchat-authorize-alias-around t]
+ ["Query Around" emchat-query-info-alias-around t]
+ ["History Around" emchat-history-around t]
+ "---"
+ ["New Log File" emchat-log-new-file t]
+ ["Contract Log" emchat-log-contract t]
+ ["Expand Log" emchat-log-expand t]
+ ["Previous Log" emchat-log-previous t]
+ ["Next Log" emchat-log-next t]
+ "---"
+ ["Mark Read" emchat-log-mark-read t]
+ ["Mark Unread" emchat-log-mark-unread t])
+ "Menu for `emchat-log-mode'.")
+
+(easy-menu-define
+ emchat-buddy-easymenu nil "Buddy" emchat-log-menu)
+
+(defvar emchat-log-mode-map
+ (let ((map (make-sparse-keymap 'emchat-log-mode-map)))
+ (set-keymap-parents map (list emchat-main-map))
+ (define-key map [delete] #'emchat-log-contract)
+ (define-key map [insert] #'emchat-log-expand)
+ (define-key map [(control up)] #'emchat-log-previous)
+ (define-key map [(control down)] #'emchat-log-next)
+ (define-key map [v] #'emchat-log-mark-unread)
+ (define-key map [c] #'emchat-log-mark-read)
+ (define-key map [W] #'emchat-alias-around)
+ (define-key map [s] #'emchat-select-alias-around)
+ (define-key map [m] #'emchat-send-message-alias-around)
+ (define-key map [u] #'emchat-send-url-alias-around)
+ (define-key map [a] #'emchat-authorize-alias-around)
+ (define-key map [i] #'emchat-query-info-alias-around)
+ (define-key map [f] #'emchat-forward-message-around)
+ (define-key map [n] #'emchat-log-next-unread)
+ (define-key map [N] #'emchat-log-next)
+ (define-key map [o] #'emchat-switch-to-buddy-buffer)
+ (define-key map [O] #'emchat-oops)
+ (define-key map [p] #'emchat-log-previous-unread)
+ (define-key map [P] #'emchat-log-previous)
+ (define-key map [t] #'emchat-history-around)
+ (define-key map [T] #'emchat-history)
+ map)
+ "Keymap for `emchat-log-mode'.")
+
+(defvar emchat-history-menu
+ '("EMchat-History"
+ ["Prev Event" emchat-history-prev t]
+ ["Next Event" emchat-history-next t]
+ ["Save Histories" emchat-history-save t]
+ ["Quit" emchat-history-bury-buffer t])
+ "Menu for `emchat-history-mod'.")
+
+(defvar emchat-history-mode-map
+ (let ((map (make-sparse-keymap 'emchat-history-mode-map)))
+ (define-key map [n] #'emchat-history-next)
+ (define-key map [p] #'emchat-history-prev)
+ (define-key map [s] #'emchat-history-save)
+ (define-key map [q] #'emchat-history-bury-buffer)
+ map)
+ "Keymap for `emchat-history-mode'.")
+
+(easy-menu-define
+ emchat-history-easymenu nil "History" emchat-history-menu)
+
+(defvar emchat-buddy-menu
+ '("EMchat-Buddy"
+ ["Select Here" emchat-select-alias-here t]
+ ["Select By Status" emchat-buddy-select-all-in-view-by-status t]
+ ["Select By Regexp" emchat-buddy-select-all-in-view-by-regexp t]
+ ["Send Message Here" emchat-send-message-alias-here t]
+ ["Send URL Here" emchat-send-url-alias-here t]
+ ["Authorize Here" emchat-authorize-alias-here t]
+ ["Query Info Here" emchat-query-info-alias-here t]
+ ["History Here" emchat-history-here-other-window t]
+ "---"
+ ["View Connected" emchat-buddy-view-connected t]
+ ["View Active" emchat-buddy-view-active t]
+ ["View All" emchat-buddy-view-all t])
+ "Menu for `emchat-buddy-mode'.")
+
+(easy-menu-define
+ emchat-log-easymenu nil "Log" emchat-buddy-menu)
+
+(defvar emchat-alias-map
+ (let ((map (make-sparse-keymap 'emchat-alias-map)))
+ (define-key map [button2] #'emchat-send-message-via-mouse)
+ map)
+ "Keymap for alias extent.")
+
+(defvar emchat-hyperlink-map
+ (let ((map (make-sparse-keymap 'emchat-hyperlink-map)))
+ (define-key map [button2] #'emchat-emphasis-visit-hyperlink-at-mouse)
+ (define-key map [return] #'emchat-emphasis-visit-hyperlink-at-point)
+ (emchat-do-in-sxemacs
+ (define-key map [(control button2)] #'emchat-curl-url-at-mouse)
+ (define-key map [(control return)] #'emchat-curl-url-at-point)
+ (define-key map [d] #'emchat-curl-url-at-point))
+ map)
+ "Keymap for the hyperlink extents.")
+
+(defvar emchat-buddy-mode-map
+ (let ((map (make-sparse-keymap 'emchat-buddy-mode-map)))
+ (set-keymap-parents map (list emchat-main-map))
+ (define-key map [W] #'emchat-alias-here)
+ (define-key map [s] #'emchat-select-alias-here)
+ (define-key map [m] #'emchat-send-message-alias-here)
+ (define-key map [u] #'emchat-send-url-alias-here)
+ (define-key map [a] #'emchat-authorize-alias-here)
+ (define-key map [i] #'emchat-query-info-alias-here)
+ (define-key map [n] #'next-line)
+ (define-key map [o] #'emchat-switch-to-log-buffer)
+ (define-key map [p] #'previous-line)
+ (define-key map [t] #'emchat-history-here-other-window)
+ map)
+ "Keymap for `emchat-buddy-mode'.")
+
+(provide 'emchat-menu)
+;;; emchat-menu.el ends here
+
--- /dev/null
+;;; emchat-meta.el --- User meta info code for EMchat
+
+;; Copyright (C) 2002 - 2007 Steve Youngs
+
+;; Author: Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created: 2002-10-02
+;; Homepage: http://www.emchat.org/
+;; Keywords: comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(defgroup emchat-meta nil
+ "User info stored in ICQ server.
+Run `emchat-update-meta-info' after changing any of these variables."
+ :prefix "emchat-user-meta-"
+ :group 'emchat)
+
+(defcustom emchat-user-meta-nickname "e-i-c-q"
+ "*Your nickname stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable.
+ICQ server refuses any string containing substring \"icq\"."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-firstname "SXEmacs"
+ "*Your first name stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable.
+ICQ server refuses any string containing substring \"icq\"."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-lastname "Linux"
+ "*Your last name stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable.
+ICQ server refuses any string containing substring \"icq\"."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-primary-email "emacs@home.com"
+ "*Your primary email address stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable.
+ICQ server refuses any string containing substring \"icq\"."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-secondary-email "emchat@home.com"
+ "*Your secondary email address stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-old-email "emchat@home.com"
+ "*Your old email address stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-city nil
+ "*Your city stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-state nil
+ "*Your state stored on the ICQ server.
+We're talking 'address' here, not online state.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-phone nil
+ "*Your phone number stored on the ICQ server.
+Do you really want to divulge this information?
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-fax nil
+ "*Your fax number stored on the ICQ server.
+Do you really want to divulge this information?
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-street nil
+ "*Your street name and number stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-cell-phone nil
+ "*Your cell phone number stored on the ICQ server.
+Do you really want to divulge this information?
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-zipcode nil
+ "*Your zip code/postal code stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-country nil
+ "*Your country stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-web-aware t
+ "*Set this to non-nil if you want your presence know on the web."
+ :type 'boolean
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-invisible nil
+ "*Set to non-nil to be \"invisible\" to other ICQ users.
+
+Having your status set to \"invisible\" is a little different from
+other statuses in that you can be \"invisible\" at the same time as
+being \"online\", \"away\", \"occ\", \"dnd\", or \"na\"."
+ :type 'boolean
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-invisibility-indicator "/inv"
+ "String to indicate your visibility.
+
+It is displayed as part of your status, eg:
+
+ [JackaLX]: <online/inv>"
+ :type 'string
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-hide-ip nil
+ "*Set to non-nil if you want to hide your IP.
+Run `emchat-update-meta-info' after modifying this variable."
+ :type 'boolean
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-authorization t
+ "*Authorization needed to add you to others' contact lists..
+Run `emchat-update-meta-info' after modifying this variable."
+ :type 'boolean
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-about
+ "Give a man a new Emacs command,
+ and he can hack for a night;
+Teach a man to make new Emacs commands,
+ and he can hack for a life time."
+ "*User 'about' info stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-homepage
+ "http://www.emchat.org/"
+ "*User homepage stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-age 65535
+ "*Your age stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable.
+65535 = not entered."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-sex 'not-entered
+ "*Your sex stored on the ICQ server.
+No, it's not an invitation.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta
+ :type '(choice (item male) (item female)
+ (item not-entered)))
+
+(defcustom emchat-user-meta-birth-year nil
+ "*Your birth year (YY) stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-birth-month nil
+ "*Your birth month (MM) stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-birth-day nil
+ "*Your birth day (DD) stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-language-1 0
+ "*User 1st language stored on the ICQ server.
+Possible values are:
+
+ 0 Unspecified 7 Chinese 17 French 27 Japanese 36 Portuguese 46 Tagalog
+55 Afrikaans 8 Croatian 18 Gaelic 28 Khmer 37 Romanian 47 Tatar
+58 Albanian 9 Czech 19 German 29 Korean 38 Russian 48 Thai
+ 1 Arabic 10 Danish 20 Greek 30 Lao 39 Serbian 49 Turkish
+59 Armenian 11 Dutch 21 Hebrew 31 Latvian 40 Slovak 50 Ukrainian
+ 2 Bhojpuri 12 English 22 Hindi 32 Lithuanian 41 Slovenian 51 Urdu
+ 3 Bulgarian 13 Esperanto 23 Hungarian 33 Malay 42 Somali 52 Vietnamese
+ 4 Burmese 14 Estonian 24 Icelandic 34 Norwegian 43 Spanish 53 Yiddish
+ 5 Cantonese 15 Farsi 25 Indonesian 57 Persian 44 Swahili 54 Yoruba
+ 6 Catalan 16 Finnish 26 Italian 35 Polish 45 Swedish
+
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-language-2 0
+ "*User 2nd language stored on the ICQ server.
+Possible values are:
+
+ 0 Unspecified 7 Chinese 17 French 27 Japanese 36 Portuguese 46 Tagalog
+55 Afrikaans 8 Croatian 18 Gaelic 28 Khmer 37 Romanian 47 Tatar
+58 Albanian 9 Czech 19 German 29 Korean 38 Russian 48 Thai
+ 1 Arabic 10 Danish 20 Greek 30 Lao 39 Serbian 49 Turkish
+59 Armenian 11 Dutch 21 Hebrew 31 Latvian 40 Slovak 50 Ukrainian
+ 2 Bhojpuri 12 English 22 Hindi 32 Lithuanian 41 Slovenian 51 Urdu
+ 3 Bulgarian 13 Esperanto 23 Hungarian 33 Malay 42 Somali 52 Vietnamese
+ 4 Burmese 14 Estonian 24 Icelandic 34 Norwegian 43 Spanish 53 Yiddish
+ 5 Cantonese 15 Farsi 25 Indonesian 57 Persian 44 Swahili 54 Yoruba
+ 6 Catalan 16 Finnish 26 Italian 35 Polish 45 Swedish
+
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-language-3 0
+ "*User 3rd language stored on the ICQ server.
+Possible values are:
+
+ 0 Unspecified 7 Chinese 17 French 27 Japanese 36 Portuguese 46 Tagalog
+55 Afrikaans 8 Croatian 18 Gaelic 28 Khmer 37 Romanian 47 Tatar
+58 Albanian 9 Czech 19 German 29 Korean 38 Russian 48 Thai
+ 1 Arabic 10 Danish 20 Greek 30 Lao 39 Serbian 49 Turkish
+59 Armenian 11 Dutch 21 Hebrew 31 Latvian 40 Slovak 50 Ukrainian
+ 2 Bhojpuri 12 English 22 Hindi 32 Lithuanian 41 Slovenian 51 Urdu
+ 3 Bulgarian 13 Esperanto 23 Hungarian 33 Malay 42 Somali 52 Vietnamese
+ 4 Burmese 14 Estonian 24 Icelandic 34 Norwegian 43 Spanish 53 Yiddish
+ 5 Cantonese 15 Farsi 25 Indonesian 57 Persian 44 Swahili 54 Yoruba
+ 6 Catalan 16 Finnish 26 Italian 35 Polish 45 Swedish
+
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-city nil
+ "*User work city stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-state nil
+ "*User work state stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-phone nil
+ "*User work phone number stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-fax nil
+ "*User work fax number stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-address nil
+ "*User work address stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-company nil
+ "*User company stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-department nil
+ "*User work department stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-position nil
+ "*User work position stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-homepage "http://www.emchat.org/"
+ "*User work homepage stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+ :group 'emchat-meta)
+
+;;; Internal variables
+
+(defvar emchat-monthnames
+ ["0" "Jan" "Feb" "Mar" "Apr" "May" "Jun"
+ "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"])
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-pack-meta-user-update-general ()
+; "Pack meta user packet 064a:03e8.
+; `M-x customize-group RET emchat-info' before this."
+; (emchat-pack
+; "\x4a\x06"
+; "\xe8\x03"
+; (emchat-int-bin (length emchat-user-meta-nickname))
+; emchat-user-meta-nickname
+; (emchat-int-bin (length emchat-user-meta-firstname))
+; emchat-user-meta-firstname
+; (emchat-int-bin (length emchat-user-meta-lastname))
+; emchat-user-meta-lastname
+; (emchat-int-bin (length emchat-user-meta-primary-email))
+; emchat-user-meta-primary-email
+; (emchat-int-bin (length emchat-user-meta-secondary-email))
+; emchat-user-meta-secondary-email
+; (emchat-int-bin (length emchat-user-meta-old-email))
+; emchat-user-meta-old-email
+; (emchat-int-bin (length emchat-user-meta-city))
+; emchat-user-meta-city
+; (emchat-int-bin (length emchat-user-meta-state))
+; emchat-user-meta-state
+; (emchat-int-bin (length emchat-user-meta-phone))
+; emchat-user-meta-phone
+; (emchat-int-bin (length emchat-user-meta-fax))
+; emchat-user-meta-fax
+; (emchat-int-bin (length emchat-user-meta-street))
+; emchat-user-meta-street
+; (emchat-int-bin (length emchat-user-meta-cell-phone))
+; emchat-user-meta-cell-phone
+; ;; zip code? only accept valid values
+; "\x00\x00\x00\x00"
+; (emchat-int-bin (car (rassoc emchat-user-meta-country emchat-country-code)))))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-pack-meta-user-security ()
+; "Pack meta user packet 064a:0424."
+; (emchat-pack
+; "\x4a\x06"
+; "\x24\x04"
+; (if emchat-user-meta-authorization
+; "\x00"
+; "\x01")
+; (if emchat-user-meta-web-aware
+; "\x01"
+; "\x00")
+; (if emchat-user-meta-hide-ip
+; "\x00"
+; "\x01")))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-pack-meta-user-update-work ()
+; "Pack meta user packet 064a:03f2.
+; `M-x customize-group RET emchat-info' before this."
+; (emchat-pack
+; "\x4a\x06"
+; "\xf2\x03"
+; (emchat-int-bin (length emchat-user-meta-work-city))
+; emchat-user-meta-work-city
+; (emchat-int-bin (length emchat-user-meta-work-state))
+; emchat-user-meta-work-state
+; (emchat-int-bin (length emchat-user-meta-work-phone))
+; emchat-user-meta-work-phone
+; (emchat-int-bin (length emchat-user-meta-work-fax))
+; emchat-user-meta-work-fax
+; (emchat-int-bin (length emchat-user-meta-work-address))
+; emchat-user-meta-work-address
+; ;; unknown
+; "\x00\x00\x00\x00\x00\x00"
+; (emchat-int-bin (length emchat-user-meta-work-company))
+; emchat-user-meta-work-company
+; (emchat-int-bin (length emchat-user-meta-work-department))
+; emchat-user-meta-work-department
+; (emchat-int-bin (length emchat-user-meta-work-position))
+; emchat-user-meta-work-position
+; ;; unknown
+; "\x00\x00"
+; (emchat-int-bin (length emchat-user-meta-work-homepage))
+; emchat-user-meta-work-homepage))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-pack-meta-user-update-more ()
+; "Pack meta user packet 064a:03fc.
+; `M-x customize-group RET emchat-info' before this."
+; (emchat-pack
+; "\x4a\x06"
+; "\xfc\x03"
+; (emchat-int-bin emchat-user-meta-age)
+; (case emchat-user-meta-sex
+; (male "\x02")
+; (female "\x01")
+; (otherwise "\x00"))
+; (emchat-int-bin (length emchat-user-meta-homepage))
+; emchat-user-meta-homepage
+; (emchat-int-byte emchat-user-meta-birth-year)
+; (emchat-int-byte emchat-user-meta-birth-month)
+; (emchat-int-byte emchat-user-meta-birth-day)
+; (emchat-int-byte emchat-user-meta-language-1)
+; (emchat-int-byte emchat-user-meta-language-2)
+; (emchat-int-byte emchat-user-meta-language-3)))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-pack-meta-user-update-about ()
+; "Pack meta user packet 064a:0406.
+; `M-x customize-group RET emchat-info' before this."
+; (emchat-pack
+; "\x4a\x06"
+; "\x06\x04"
+; (emchat-int-bin (length emchat-user-meta-about))
+; emchat-user-meta-about))
+
+;;; FIXME: This needs to be updated for v8
+; (defvar emchat-do-meta-alist
+; '(("\x64\x00" . emchat-do-meta-user-update-general-confirm)
+; ("\x6e\x00" . emchat-do-meta-user-update-work-confirm)
+; ("\x78\x00" . emchat-do-meta-user-update-more-confirm)
+; ("\x82\x00" . emchat-do-meta-user-update-about-confirm)
+; ("\xaa\x00" . emchat-do-meta-user-password)
+; ("\xc8\x00" . emchat-do-meta-user-general)
+; ("\xd2\x00" . emchat-do-meta-user-work)
+; ("\xdc\x00" . emchat-do-meta-user-more)
+; ("\xe6\x00" . emchat-do-meta-user-about)
+; ("\xf0\x00" . emchat-do-meta-user-interest)
+; ("\xfa\x00" . emchat-do-meta-user-background)
+; ("\x0e\x01" . emchat-do-meta-user-picture)
+; ("\x9a\x01" . emchat-do-meta-user-found))
+; "Handlers for server packet meta user subcommands.")
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-meta-user (packet)
+; "Handle server command 03de in PACKET."
+; (let* ((subcommand (substring packet 21 23))
+; (result (substring packet 23 24))
+; (data (substring packet 24))
+; (handler (cdr (assoc subcommand emchat-do-meta-alist))))
+; (if (not (equal result "\x0a"))
+; (emchat-log-info "meta user command failed")
+; (if (fboundp handler)
+; (funcall handler data)
+; (emchat-do-meta-user-unknown packet)))))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-meta-user-unknown (packet)
+; "Handle server command 03de unknown subcommands in PACKET."
+; (emchat-log-debug
+; "meta user subcommand %s unhandled = %s"
+; (emchat-bin-hex (substring packet 21 23))
+; (emchat-bin-pretty-hex (substring packet 24))))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-update-meta-info ()
+; "Update user meta info on the ICQ server.
+; Run this after changing any meta user info variables."
+; (interactive)
+; ;(emchat-send (emchat-pack-update-authorization))
+; (emchat-send (emchat-pack-meta-user-security))
+; (emchat-send (emchat-pack-meta-user-update-general))
+; (emchat-send (emchat-pack-meta-user-update-work))
+; (emchat-send (emchat-pack-meta-user-update-more))
+; (emchat-send (emchat-pack-meta-user-update-about)))
+
+(provide 'emchat-meta)
+
+;;; emchat-status.el ends here
+
--- /dev/null
+;;; emchat-report.el --- Generate a bug report -*-Emacs-Lisp-*-
+
+;; Copyright (C) 2001 - 2007 Steve Youngs
+
+;; Author: Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Keywords: bug-report
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;; To submit a bug report use: M-x emchat-report-bug
+;; To send general comments/questions use: M-x emchat-email-author
+
+;;; Code:
+
+(autoload 'emchat-version "emchat"
+ "Version of emchat you are currently using." t nil)
+(require 'sendmail)
+(require 'shadow)
+(require 'gnus-msg)
+(require 'gnus-util)
+(require 'message)
+
+;; To keep the byte-compiler from spewing out warnings.
+(eval-when-compile
+ (defvar after-sep-pos)
+ (defvar final-resting-place)
+ (defvar emchat-version)
+ (require 'font-lock)
+ (require 'yow)
+ (require 'pp))
+
+
+;;; Variables
+
+(defcustom emchat-report-bug-send-init nil
+ "*If non-nil, include the user's init.el file in the bug report."
+ :group 'emchat-option
+ :type 'boolean)
+
+;;; Internal variables
+
+(defconst emchat-report-salutations
+ ["Dear bug team:"
+ "Ciao bug team:"
+ "Salut bug team:"
+ "Guten Tag bug team:"
+ "To whom it may concern:"
+ "Fellow EMchat'ers:"
+ "Yo bug team:"
+ "G'day bug team:"
+ "Greetings Earthlings:"]
+ "A list of salutations used for `emchat-report-bug'.")
+
+(defvar emchat-bug-address
+ "EMchat Bugs <emchat-bugs@emchat.org>"
+ "The address used for submitting bug reports.")
+
+(defvar emchat-report-blurb nil)
+
+;;; Functions
+
+(defun emchat-report-pre-hook ()
+ "Pre hook run by report-submit-bug-report."
+ (message-goto-subject)
+ (insert "EMchat bug: ")
+ (if emchat-report-blurb
+ (progn
+ (mail-text)
+ (insert "\n" emchat-report-blurb "\n"))))
+
+(defun emchat-report-post-hook ()
+ "Post hook run by report-submit-bug-report."
+ (save-excursion
+ (message-goto-subject)
+ (font-lock-fontify-buffer)
+ (let ((subj (read-string "Subject header: ")))
+ (if (string-equal subj "")
+ (subst-char-in-region
+ (point)
+ (progn
+ (insert
+ (if (or (fboundp 'yow) (load "yow" t t)) (yow) ""))
+ (point))
+ ?\n ?\ )
+ (insert subj)))))
+
+;; Stolen from Gnus.
+(defun emchat-report-debug ()
+ "Go through the EMchat source files and report what variables have been changed.
+The source file has to be in the load path."
+ (let ((files '("emchat-buddy.el" "emchat-comm.el" "emchat-curl.el" "emchat-doctor.el"
+ "emchat-emphasis.el" "emchat-log.el" "emchat-meta.el" "emchat-report.el"
+ "emchat-status.el" "emchat-toolbar.el" "emchat-track.el" "emchat-wharf.el"
+ "emchat-world.el" "emchat-xwem.el" "emchat.el"))
+ (point (point))
+ file expr olist sym)
+ (message "Please wait while we snoop your variables...")
+ (sit-for 0)
+ ;; Go through all the files looking for non-default values for variables.
+ (save-excursion
+ (set-buffer (get-buffer-create " *emchat bug info*"))
+ (while files
+ (erase-buffer)
+ (when (and (setq file (locate-library (pop files)))
+ (file-exists-p file))
+ (insert-file-contents file)
+ (goto-char (point-min))
+ (if (not (re-search-forward "^;;* *Internal variables" nil t))
+ (message "Malformed sources in file %s" file)
+ (narrow-to-region (point-min) (point))
+ (goto-char (point-min))
+ (while (setq expr (ignore-errors (read (current-buffer))))
+ (ignore-errors
+ (and (or (eq (car expr) 'defvar)
+ (eq (car expr) 'defcustom))
+ (stringp (nth 3 expr))
+ (or (not (boundp (nth 1 expr)))
+ (not (equal (eval (nth 2 expr))
+ (symbol-value (nth 1 expr)))))
+ (push (nth 1 expr) olist)))))))
+ (kill-buffer (current-buffer)))
+ (when (setq olist (nreverse olist))
+ (insert "\n"))
+ (while olist
+ (when (boundp (car olist))
+ (condition-case ()
+ (pp `(setq ,(car olist)
+ ,(if (or (consp (setq sym (symbol-value (car olist))))
+ (and (symbolp sym)
+ (not (or (eq sym nil)
+ (eq sym t)))))
+ (list 'quote (symbol-value (car olist)))
+ (symbol-value (car olist))))
+ (current-buffer))
+ (error
+ (format "(setq %s 'whatever)\n" (car olist)))))
+ ;(insert ";; (makeunbound '" (symbol-name (car olist)) ")\n"))
+ (setq olist (cdr olist)))
+ ;; Remove any control chars - they seem to cause trouble for some
+ ;; mailers. (Byte-compiled output from the stuff above.)
+ (goto-char point)
+ (while (re-search-forward "[\000-\010\013-\037\200-\237]" nil t)
+ (replace-match (format "\\%03o" (string-to-char (match-string 0)))
+ t t))))
+
+(defun emchat-prepare-report ()
+ "Grabs the variables, features to include in bug report.
+Then put it all into a mail buffer, nicely formatted."
+ (message-goto-to)
+ (insert emchat-bug-address)
+ (message-goto-body)
+ (forward-line 1)
+ (setq after-sep-pos (point))
+ (setq final-resting-place (point-marker))
+ (insert
+ "\n\n"
+ "===============================================================\n"
+ "System info to help the EMchat boys and girls try to fix your bug:\n"
+ "==============================================================="
+ "\n\n")
+ (emchat-version 1)
+ ;; Insert all the EMchat vars that have been changed from default.
+ ;; The actual work for this is done in `emchat-bug-debug', but it
+ ;; needs to be called toward the end of this function.
+ (insert "\n\nEMchat variables of note:\n----------------------\n")
+ ;; Insert the output of 'describe-installation'.
+ (insert "\n\n"
+ (symbol-value 'Installation-string))
+ ;; Load-path shadows can cause some grief.
+ (flet ((append-message
+ (&rest args) ())
+ (clear-message
+ (&optional label frame stdout-p no-restore)
+ ()))
+ (insert "\n\nLoad-Path Lisp Shadows:\n"
+ "----------------------\n")
+ (let ((before-shadows (point)))
+ (insert
+ (format "%s"
+ (find-emacs-lisp-shadows load-path)))
+ (save-restriction
+ (narrow-to-region before-shadows (point))
+ (fill-paragraph t)
+ (insert "\n"))))
+ ;; Insert a list of installed packages.
+ (insert "\n\nInstalled XEmacs Packages:\n"
+ "-------------------------\n")
+ (cl-prettyprint
+ (symbol-value 'packages-package-list))
+ (insert "\n")
+ ;; Insert a list of loaded features
+ (let ((before-features (point)))
+ (insert
+ (format "\n\nFeatures:\n--------\n\n%s" (symbol-value 'features)))
+ (save-restriction
+ (narrow-to-region before-features (point))
+ (fill-paragraph t)
+ (insert "\n\n")))
+ ;; Insert the contents of the user's init file if it exists
+ ;; and the user wants it sent.
+ (if emchat-report-bug-send-init
+ (if (file-readable-p user-init-file)
+ (save-excursion
+ (message-goto-signature)
+ (forward-line -3)
+ (beginning-of-line)
+ (insert "\n\nUser Init File:\n--------------\n\n")
+ (insert-file-contents user-init-file))))
+ (emchat-report-pre-hook)
+ (emchat-report-post-hook)
+ (mail-text)
+ (insert
+ (aref emchat-report-salutations
+ (% (+ (% (random) 1000) 1000)
+ (length emchat-report-salutations))) "\n")
+ (re-search-forward "EMchat variables of note:" nil t)
+ (forward-line 2)
+ (emchat-report-debug)
+ (goto-char final-resting-place)
+ (set-marker final-resting-place nil)
+ (message "Please enter your report. Type C-c C-c to send, C-x k to abort."))
+
+;;;###autoload
+(defun emchat-report-bug (&optional blurb no-confirm)
+ "Submit a bug report for emchat.
+Optional argument BLURB is a string that adds a preamble to the bug report.
+Optional argument NO-CONFIRM if 't' will not ask for confirmation.
+
+If you have Gnus it will be used, otherwise the standard XEmacs mail
+command is used.
+
+Yes, it's all part of a secret plot to make more people use
+the MUA of Gods. Bwahahaha."
+ (interactive)
+ (if (or no-confirm
+ (y-or-n-p "Do you want to submit a bug report on EMchat? "))
+ (progn
+ (setq emchat-report-blurb blurb)
+ (if (featurep 'gnus)
+ (progn
+ (unless (gnus-alive-p)
+ (gnus))
+ (gnus-group-mail 1)
+ (emchat-prepare-report))
+ (mail)
+ (emchat-prepare-report)))))
+
+;;; email-author code
+
+(defconst emchat-email-salutations
+ ["Dear Steve,"
+ "Ciao Steve,"
+ "Guten Tag Steve,"
+ "To whom it may concern:"
+ "Bonjour Steve,"
+ "Yo! EMchat Dude!"
+ "G'day Steve,"
+ "Hey Man,"
+ "Greetings Earthling:"]
+ "A list of salutations used for `emchat-email-author'.")
+
+(defun emchat-prepare-email-author ()
+ "Prepare the mail buffer for `emchat-email-author'."
+ (message-goto-to)
+ (insert "Steve Youngs <steve@emchat.org>")
+ (message-goto-cc)
+ (insert "EMchat Users <emchat-users@emchat.org>")
+ (message-goto-subject)
+ (let ((subj (read-string "Subject header: ")))
+ (if (string-equal subj "")
+ (subst-char-in-region
+ (point)
+ (progn
+ (insert
+ (if (or (fboundp 'yow) (load "yow" t t)) (yow) ""))
+ (point))
+ ?\n ?\ )
+ (insert subj)))
+ (message-goto-body)
+ (emchat-version 1)
+ (insert "\n\n"
+ (aref emchat-email-salutations
+ (% (+ (% (random) 1000) 1000)
+ (length emchat-email-salutations))) "\n\n\n")
+ (forward-line -1))
+
+;;;###autoload
+(defun emchat-email-author ()
+ "Email comments or money to author.
+
+Uses Gnus if available, otherwise standard mail command."
+ (interactive)
+ (if (y-or-n-p "Do you want to send comments to the EMchat author? ")
+ (progn
+ (if (featurep 'gnus)
+ (progn
+ (unless (gnus-alive-p)
+ (gnus))
+ (gnus-group-mail 1)
+ (emchat-prepare-email-author))
+ (mail)
+ (emchat-prepare-email-author)))))
+
+(provide 'emchat-report)
+
+;;; emchat-report.el ends here
--- /dev/null
+;; emchat-setup.el --- Setup user directory and files for EMchat.
+
+;; Copyright (C) 2002 - 2007 Steve Youngs
+
+;; Author: Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created: 2002-10-03
+;; Homepage: http://www.emchat.org/
+;; Keywords: comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(defconst emchat-world-user-file-template
+ "
+Literally you can put anything you like in this resource file, such as
+this introduction. EMchat will only consider a line to be a valid buddy
+if...
+
+ -- `:icq' starts at column zero (there's no leading whitespace or
+ characters).
+
+ -- There is one space between `:icq' and a UIN.
+
+ -- There is one space between a UIN and a buddy name.
+
+ -- The buddy name does NOT contain any colon `:' characters.
+ Buddy names can contain whitespace anywhere except as the
+ first character.
+
+ -- There is one space between the buddy name and any group names.
+ Group names begin with a colon `:'.
+
+So, for example...
+
+:icq 34307457 emchat
+:icq 12345678 me
+:icq 88888888 the queen :royalty
+
+This way, it defines three buddies: \"emchat\", \"me\", and \"the
+queen\". It reads alias name until the end of the line, or until the
+first group name. In that example, the buddy \"the queen\" is in
+the group `:royalty'.
+
+Adding your own UIN:
+
+Just change \"12345678 me\" above to your UIN/alias. And don't
+forget to change the (setq emchat-user-alias \"me\") line in your
+`user-init-file' to match.
+
+BTW, that 1st buddy up there, 34307457 emchat, is a valid UIN, it's
+mine. :-)
+
+Remember to M-x emchat-world-update after changing this rc file.
+
+"
+ "Template used to create user's initial EMchat rc file.")
+
+(eval-when-compile
+ (defvar emchat-history-directory))
+
+;;;###autoload
+(defun emchat-setup ()
+ "Setup your personal EMchat directory.
+
+This directory, which defaults to '~/.emchat/', holds the resource file
+for your ICQ contacts and any log files. It's also a good place to
+put your sound files."
+ (interactive)
+ (unless (featurep '(and emchat emchat-history emchat-world emchat-setup))
+ (require 'emchat)
+ (require 'emchat-history)
+ (require 'emchat-world)
+ (require 'emchat-setup))
+ ;; Create necessary directories.
+ (unless (file-directory-p emchat-directory)
+ (make-directory emchat-directory t))
+ (unless (file-directory-p emchat-sound-directory)
+ (make-directory emchat-sound-directory t))
+ (unless (file-directory-p emchat-history-directory)
+ (make-directory emchat-history-directory t))
+ ;; Create a world file if needed.
+ (unless (file-exists-p emchat-world-rc-filename)
+ (save-excursion
+ (switch-to-buffer (find-file emchat-world-rc-filename))
+ (insert (symbol-value 'emchat-world-user-file-template))
+ (save-buffer)
+ (kill-buffer nil)))
+ (message "Don't forget to edit %s to your requirements"
+ emchat-world-rc-filename))
+
+(provide 'emchat-setup)
+;;; emchat-setup.el ends here
--- /dev/null
+;;; emchat-status.el --- Status code for EMchat
+
+;; Copyright (C) 2002 - 2007 Steve Youngs
+
+;; Author: Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created: 2002-10-02
+;; Homepage: http://www.emchat.org/
+;; Keywords: comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(eval-and-compile
+ (require 'emchat-log)
+ (require 'emchat-world)
+ (require 'emchat-meta)
+ (require 'emchat)
+ (require 'wid-edit))
+
+(eval-when-compile
+ (defvar emchat-buddy-view)
+ (defvar emchat-wharf-frame-use-p))
+
+(autoload 'emchat-buddy-update-face "emchat-buddy")
+
+
+(defcustom emchat-buddy-status-color-hint-flag t
+ "*Non-nil means put status color hints."
+ :type 'boolean
+ :group 'emchat-buddy)
+
+;;;###autoload
+(defcustom emchat-status-window-height 8
+ "*Height of window for `emchat-status-buffer'."
+ :group 'emchat-interface)
+
+(defcustom emchat-status-use-gutter nil
+ "*When non-nil, display statuses in the gutter, not in a buffer."
+ :type 'boolean
+ :group 'emchat-interface)
+
+(defcustom emchat-status-gutter-orientation 'top
+ "Where to display the status gutter.
+
+Valid values are: top, bottom, left, right."
+ :type '(choice (item :tag "Top" :value top)
+ (item :tag "Bottom" :value bottom)
+ (item :tag "Left" :value left)
+ (item :tag "Right" :value right))
+ :group 'emchat-interface)
+
+;;;###autoload
+(defvar emchat-valid-statuses
+ '("online" "away" "occ" "dnd" "ffc" "na")
+ "All statuses valid for selection.
+Used by `emchat-change-status' and in `emchat-buddy-buffer'.")
+
+;;;###autoload
+(defcustom emchat-user-initial-status "online"
+ "*Initial user status when login."
+ :group 'emchat-option
+ :type
+ (cons 'choice
+ (mapcar
+ (lambda (x) (list 'item x))
+ emchat-valid-statuses)))
+
+(defcustom emchat-status-update-hook nil
+ "*Hooks to run when a buddy change his status.
+Dynamically ALIAS and STATUS are binded to be used in hooks."
+ :group 'emchat-option
+ :type 'hook)
+
+(defface emchat-face-online
+ '((((background dark))
+ (:foreground "green"))
+ (((background light))
+ (:foreground "green4")))
+ "Face for ONLINE status."
+ :group 'emchat-buddy)
+
+(defface emchat-face-away
+ '((((background dark))
+ (:foreground "red"))
+ (((background light))
+ (:foreground "red4")))
+ "Face for AWAY status."
+ :group 'emchat-buddy)
+
+(defface emchat-face-occ
+ '((((background dark))
+ (:foreground "orange"))
+ (((background light))
+ (:foreground "orange4")))
+ "Face for OCCUPIED status."
+ :group 'emchat-buddy)
+
+(defface emchat-face-dnd
+ '((((background dark))
+ (:foreground "lightblue"))
+ (((background light))
+ (:foreground "blue")))
+ "Face for DO NOT DISTURB status."
+ :group 'emchat-buddy)
+
+(defface emchat-face-ffc
+ '((((background dark))
+ (:foreground "yellow"))
+ (((background light))
+ (:foreground "yellow4")))
+ "Face for FREE FOR CHAT status."
+ :group 'emchat-buddy)
+
+(defface emchat-face-na
+ '((((background dark))
+ (:foreground "pink"))
+ (((background light))
+ (:foreground "deeppink")))
+ "Face for NOT AVAILABLE status."
+ :group 'emchat-buddy)
+
+(defface emchat-face-invisible
+ '((((background dark))
+ (:foreground "grey"))
+ (((background light))
+ (:foreground "grey40")))
+ "Face for OFFLINE status."
+ :group 'emchat-buddy)
+
+;;; Internal variables
+
+(defvar emchat-statuses
+ ;; basically status is only ONE byte (except for invisible?)
+ ;; byte after status byte is random
+ '((online "online" emchat-face-online)
+ (away "away" emchat-face-away emchat-auto-reply-away)
+ (na "na" emchat-face-na emchat-auto-reply-na)
+ (occupied "occ" emchat-face-occ emchat-auto-reply-occ)
+ (dnd "dnd" emchat-face-dnd emchat-auto-reply-dnd)
+ (ffc "ffc" emchat-face-ffc)
+ (offline "offline" nil)
+ (invisible "invisible" emchat-face-invisible))
+ "Status info: v8 status, text code, face, auto-reply.")
+
+(defun emchat-status-face (name)
+ "Return the face of status from its NAME."
+ (caddar
+ (member* name emchat-statuses
+ :key 'second
+ :test 'string=)))
+
+(defun emchat-status-v8 (name)
+ "Return the symbol for status NAME."
+ (caar
+ (member* name emchat-statuses
+ :key 'second
+ :test 'string=)))
+
+(defun emchat-status-auto-reply (name)
+ "Return the symbol of auto-reply of status from its NAME."
+ (fourth (car
+ (member* name emchat-statuses
+ :key 'second
+ :test 'string=))))
+
+(defun emchat-status-idle-reply (name)
+ "Return the symbol of idle-reply of status from its NAME."
+ (let ((sym (emchat-status-auto-reply name)))
+ (with-temp-buffer
+ (insert (symbol-name sym))
+ (while (search-backward "auto" nil t)
+ (replace-match "idle" nil t))
+ (intern (buffer-string)))))
+
+(defun emchat-status-name (proto-status)
+ "Return the name of status from its the binary string BIN."
+ (cadr (assoc proto-status emchat-statuses)))
+
+(defun emchat-buddy-update-status (alias status)
+ "Update ALIAS with new STATUS."
+ ;; update alias variables
+ (unless (member status (mapcar 'second emchat-statuses))
+ (push (cons 'unknown-status emchat-recent-packet)
+ emchat-error-packets)
+ (emchat-log-error "Unknown status: %s" status)
+ (setq status "online")) ; assumed online
+
+ ;; kludge-o-matic
+ (when (and (equal alias emchat-user-alias)
+ (string= status "invisible"))
+ (setq status emchat-user-status))
+
+ (unless (emchat-world-getf alias 'status)
+ (emchat-world-putf alias 'status "offline"))
+
+ (unless (equal status (emchat-world-getf alias 'status))
+ (emchat-world-putf alias 'status status)
+ (emchat-log-buddy-status alias "***| %s" status)
+ (when (string= status "online")
+ (emchat-play-sound-maybe 'buddy-sound))
+ (if (string= status "offline")
+ (if (member alias emchat-connected-aliases)
+ (setq emchat-connected-aliases
+ (delete alias emchat-connected-aliases))
+ (emchat-log-buddy-status alias "***| has been invisible"))
+ ;; if not offline
+ (add-to-list 'emchat-connected-aliases alias))
+
+ ;; update buffer
+
+ ;; view != all + offline -> delete
+ ;; view = all + offline -> offline-face
+ (if (and (string= status "offline")
+ (not (eq emchat-buddy-view 'emchat-all-aliases)))
+ (emchat-buddy-update-face alias 'delete)
+ (if (or (member alias (symbol-value emchat-buddy-view))
+ (string= status "offline"))
+ (emchat-buddy-update-face alias)))))
+
+;;;###autoload
+(defvar emchat-user-status "offline"
+ "Current user status.")
+
+(defun emchat-do-status-update (ectx uin status)
+ "Handle server command 01a4 in PACKET."
+ (let ((alias (emchat-uin-alias (emchat-stringular-uin uin)))
+ (status (emchat-status-name status)))
+ (emchat-buddy-update-status alias status)
+ (run-hooks 'emchat-status-update-hook)))
+
+(defun emchat-turn-on-invisibility ()
+ (emchat-v8-snac-cli-setstatus
+ emchat-ctx (append (list (emchat-status-v8 emchat-user-status))
+ (and emchat-user-meta-web-aware '(web-aware))
+ '(invisible)))
+ (emchat-log-buddy-status emchat-user-alias "***| %s (invisible)" emchat-user-status)
+ (setq emchat-user-meta-invisible t))
+
+(defun emchat-turn-off-invisibility ()
+ (emchat-v8-snac-cli-setstatus
+ emchat-ctx (append (list (emchat-status-v8 emchat-user-status))
+ (and emchat-user-meta-web-aware '(web-aware))))
+ (emchat-log-buddy-status emchat-user-alias "***| %s (visible)" emchat-user-status)
+ (setq emchat-user-meta-invisible nil))
+
+(defun emchat-toggle-invisibility ()
+ "Toggle \"invisible\" status."
+ (interactive)
+ (setq emchat-user-meta-invisible (null emchat-user-meta-invisible))
+ (if emchat-user-meta-invisible
+ (emchat-turn-on-invisibility)
+ (emchat-turn-off-invisibility))
+ (with-current-buffer emchat-log-buffer
+ (emchat-log-update-modeline)))
+
+(defun emchat-change-status (status &optional no-network)
+ "Change to new STATUS.
+Non-nil NO-NETWORK means not to send any network packet, only update
+variable and modeline."
+ (interactive
+ (list (emchat-completing-read "status: " emchat-valid-statuses nil t)))
+ (unless (equal status emchat-user-status)
+ (when emchat-user-auto-away-p
+ (setq emchat-user-auto-away-p nil))
+ (emchat-log-system "Changed status to %s" status)
+ (when (equal status "online")
+ (setq emchat-auto-reply-never emchat-auto-response-never-send-to)
+ (loop for alias in emchat-online-notifiers
+ do (emchat-v8-send-simple-message
+ emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias))
+ "I'm back online.
+You won't be notified again unless you re-request
+it with \",,notify-me\".")
+ do (emchat-log-system (format "Online notification sent to: %s" alias)))
+ (setq emchat-online-notifiers nil))
+ (setq emchat-user-status status)
+ (when emchat-wharf-frame-use-p
+ (declare-fboundp (emchat-wharf-update-status)))
+ (redraw-modeline 'all)
+ (unless no-network
+ (emchat-v8-snac-cli-setstatus
+ emchat-ctx (append (list (emchat-status-v8 status))
+ (and emchat-user-meta-web-aware '(web-aware))
+ (and emchat-user-meta-invisible '(invisible)))))))
+
+;;;###autoload
+(defvar emchat-status-buffer nil
+ "Buffer for statuses.")
+
+;;;###autoload
+(defun emchat-status-show-buffer (&optional new no-select)
+ "Switch to `emchat-status-buffer'.
+Create buffer if buffer does not exists already or
+NEW is non-nil.
+Don't select status window if NO-SELECT is non-nil."
+ (interactive)
+ (when (or (not (buffer-live-p emchat-status-buffer))
+ new)
+ (setq emchat-status-buffer (get-buffer-create "*Status*"))
+ (set-buffer emchat-status-buffer)
+ (set-specifier horizontal-scrollbar-visible-p nil
+ (cons (current-buffer) nil))
+ (set-specifier vertical-scrollbar-visible-p nil
+ (cons (current-buffer) nil))
+ (set-specifier has-modeline-p nil
+ (cons (current-buffer) nil))
+ (erase-buffer)
+ (set (make-local-variable 'widget-button-face) 'emchat-face-online)
+ (widget-create 'link
+ :help-echo "Change status to \"Online\""
+ :action (lambda (&rest ignore)
+ (emchat-change-status "online"))
+ "Online")
+ (widget-insert "\n")
+ (set (make-local-variable 'widget-button-face) 'emchat-face-away)
+ (widget-create 'link
+ :help-echo "Change status to \"Away\""
+ :action (lambda (&rest ignore)
+ (emchat-change-status "away"))
+ "Away")
+ (widget-insert "\n")
+ (set (make-local-variable 'widget-button-face) 'emchat-face-occ)
+ (widget-create 'link
+ :help-echo "Change status to \"Occupied\""
+ :action (lambda (&rest ignore)
+ (emchat-change-status "occ"))
+ "Occupied")
+ (widget-insert "\n")
+ (set (make-local-variable 'widget-button-face) 'emchat-face-dnd)
+ (widget-create 'link
+ :help-echo "Change status to \"Do Not Disturb\""
+ :action (lambda (&rest ignore)
+ (emchat-change-status "dnd"))
+ "Do Not Disturb")
+ (widget-insert "\n")
+ (set (make-local-variable 'widget-button-face) 'emchat-face-na)
+ (widget-create 'link
+ :help-echo "Change status to \"Not Available\""
+ :action (lambda (&rest ignore)
+ (emchat-change-status "na"))
+ "Not Available")
+ (widget-insert "\n")
+ (set (make-local-variable 'widget-button-face) 'emchat-face-ffc)
+ (widget-create 'link
+ :help-echo "Change status to \"Free For Chat\""
+ :action (lambda (&rest ignore)
+ (emchat-change-status "ffc"))
+ "Free For Chat")
+ (widget-insert "\n")
+ (set (make-local-variable 'widget-button-face) 'emchat-face-invisible)
+ (widget-create 'link
+ :help-echo "Toggle your visibility"
+ :action (lambda (&rest ignore)
+ (emchat-toggle-invisibility))
+ "Invisible on/off")
+ (toggle-read-only 1)
+ (unless no-select
+ (switch-to-buffer emchat-status-buffer))))
+
+;;; Status gutter
+;;; WARNING: This is experimental and unfinished.
+(defvar emchat-status-gutter-tab nil
+ "A tab widget in the gutter for switching online statuses.
+Do not set this. Use `set-glyph-image' to change the properties of
+the tab.")
+
+(defun emchat-status-maybe-login ()
+ "Convenience function for the status gutter.
+If a connection to the ICQ server exists, just change status to
+online, otherwise login."
+ (if (emchat-connected-p emchat-ctx)
+ (emchat-change-status "online")
+ (emchat-login)))
+
+(defvar emchat-status-tabs
+ '(["Online" (emchat-status-maybe-login)
+ :selected (equal emchat-user-status "online")]
+ ["Away" (emchat-change-status "away")
+ :selected (equal emchat-user-status "away")]
+ ["Occupied" (emchat-change-status "occ")
+ :selected (equal emchat-user-status "occ")]
+ ["Do Not Disturb" (emchat-change-status "dnd")
+ :selected (equal emchat-user-status "dnd")]
+ ["Not Available" (emchat-change-status "na")
+ :selected (equal emchat-user-status "na")]
+ ["FFC" (emchat-change-status "ffc")
+ :selected (equal emchat-user-status "ffc")]
+ ["Inv on/off" (emchat-toggle-invisibility) :selected nil]
+ ["Offline" (emchat-logout)
+ :selected (equal emchat-user-status "offline")])
+ "Buttons for the EMchat status gutter.")
+
+;;; FIXME: Left and right gutters are broken, also, I don't like
+;;; setting `default-gutter-position' to change the orientation
+;;; although the docs seem to suggest that this is the only way to
+;;; do it...
+;; ,----[ C-h v right-gutter RET ]
+;; | `right-gutter' is a built-in constant specifier variable.
+;; |
+;; | Value: #<gutter-specifier global=<unspecified> fallback=((nil)) 0x145>
+;; |
+;; | Documentation:
+;; | Specifier for the gutter at the right edge of the frame.
+;; | Use `set-specifier' to change this.
+;; | See `default-gutter' for a description of a valid gutter instantiator.
+;; |
+;; | Note that, unless the `default-gutter-position' is `right', by
+;; | default the height of the right gutter (controlled by
+;; | `right-gutter-width') is 0; thus, a right gutter will not be
+;; | displayed even if you provide a value for `right-gutter'.
+;; `----
+
+(defun emchat-add-tab-to-gutter ()
+ (let* ((gutter-string (copy-sequence "\n"))
+ (status-gutter-extent (make-extent 0 1 gutter-string)))
+ (set-extent-begin-glyph status-gutter-extent
+ (setq emchat-status-gutter-tab
+ (make-glyph)))
+ (mapcar
+ (lambda (x)
+ (remove-gutter-element top-gutter 'status-tab emchat-frame x)
+ (remove-gutter-element bottom-gutter 'status-tab emchat-frame x)
+ (remove-gutter-element left-gutter 'status-tab emchat-frame x)
+ (remove-gutter-element right-gutter 'status-tab emchat-frame x))
+ (console-type-list))
+ (mapcar
+ (lambda (x)
+ (when (valid-image-instantiator-format-p 'tab-control x)
+ (cond ((eq emchat-status-gutter-orientation 'top)
+ (set-default-gutter-position 'top)
+ (set-specifier top-gutter-visible-p t emchat-frame x)
+ (set-specifier top-gutter-border-width 0 emchat-frame x)
+ (set-gutter-element top-gutter 'status-tab
+ gutter-string emchat-frame x))
+ ((eq emchat-status-gutter-orientation 'bottom)
+ (set-default-gutter-position 'bottom)
+ (set-specifier bottom-gutter-visible-p t emchat-frame x)
+ (set-specifier bottom-gutter-border-width 0 emchat-frame x)
+ (set-gutter-element bottom-gutter 'status-tab
+ gutter-string emchat-frame x))
+ ((eq emchat-status-gutter-orientation 'left)
+ (set-default-gutter-position 'left)
+ (set-specifier left-gutter-visible-p t emchat-frame x)
+ (set-specifier left-gutter-border-width 0 emchat-frame x)
+ (set-gutter-element left-gutter 'status-tab
+ gutter-string emchat-frame x))
+ ((eq emchat-status-gutter-orientation 'right)
+ (set-default-gutter-position 'right)
+ (set-specifier right-gutter-visible-p t emchat-frame x)
+ (set-specifier right-gutter-border-width 0 emchat-frame x)
+ (set-gutter-element right-gutter 'status-tab
+ gutter-string emchat-frame x)))))
+ (console-type-list))))
+
+;;; FIXME: When the gutter code in (S)XEmacs can put different faces
+;;; on different buttons update this so that the status tabs have the
+;;; right faces... emchat-face-{online,away,na,occ,dnd,ffc,invisible}.
+(defun emchat-update-tab-in-gutter ()
+ "Update the tab control in the gutter area."
+ (unless (or (window-dedicated-p (frame-selected-window emchat-frame))
+ (frame-property emchat-frame 'popup))
+ (emchat-add-tab-to-gutter)
+ (when (valid-image-instantiator-format-p 'tab-control emchat-frame)
+ (set-glyph-image
+ emchat-status-gutter-tab
+ (vector 'tab-control :descriptor "Status"
+ :face 'bold
+ :orientation emchat-status-gutter-orientation
+ (if (or (eq emchat-status-gutter-orientation 'top)
+ (eq emchat-status-gutter-orientation 'bottom))
+ :pixel-width :pixel-height)
+ (if (or (eq emchat-status-gutter-orientation 'top)
+ (eq emchat-status-gutter-orientation 'bottom))
+ '(gutter-pixel-width) '(gutter-pixel-height))
+ :items (eval 'emchat-status-tabs))
+ emchat-frame)
+ ;; set-glyph-image will not make the gutter dirty
+ (set-gutter-dirty-p emchat-status-gutter-orientation))))
+
+(provide 'emchat-status)
+
+;;; emchat-status.el ends here
--- /dev/null
+;;; emchat-toolbar.el --- A toolbar for EMchat -*-Emacs-Lisp-*-
+
+;; Copyright (C) 2000 - 2007 Steve Youngs
+
+;; Author: Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Keywords: emchat, toolbar, comm
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+;; A toolbar for emchat.
+;;
+
+(eval-and-compile
+ (require 'emchat-meta)
+ (require 'emchat-log))
+
+(autoload 'emchat-change-password "emchat" nil t)
+(autoload 'emchat-send-message-alias-here "emchat" nil t)
+(autoload 'emchat-send-message "emchat" nil t)
+(autoload 'emchat-send-url-alias-here "emchat" nil t)
+(autoload 'emchat-send-url "emchat" nil t)
+(autoload 'emchat-query-info-alias-around "emchat" nil t)
+(autoload 'emchat-query-info "emchat" nil t)
+(autoload 'emchat-search "emchat" nil t)
+(autoload 'emchat-authorize-alias-here "emchat" nil t)
+(autoload 'emchat-login "emchat" nil t)
+(autoload 'emchat-logout "emchat" nil t)
+(autoload 'emchat-exit "emchat" nil t)
+
+;;; Code:
+
+(defcustom emchat-use-toolbar (if (and (featurep 'toolbar)
+ (featurep 'xpm))
+ 'default-toolbar
+ nil)
+ "*If nil, do not use a toolbar.
+If it is non-nil, it must be a toolbar. The five valid values are
+`default-toolbar', `top-toolbar', `bottom-toolbar',
+`right-toolbar', and `left-toolbar'."
+ :type '(choice (const default-toolbar)
+ (const top-toolbar) (const bottom-toolbar)
+ (const left-toolbar) (const right-toolbar)
+ (const :tag "no toolbar" nil))
+ :group 'emchat-interface)
+
+(defvar emchat-password-icon
+ (toolbar-make-button-list
+ (expand-file-name "password.xpm" emchat-glyph-dir))
+ "A password toolbar icon.")
+
+(defvar emchat-send-message-here-icon
+ (toolbar-make-button-list
+ (expand-file-name "msg-here.xpm" emchat-glyph-dir))
+ "A send message toolbar icon.")
+
+(defvar emchat-send-message-around-icon
+ (toolbar-make-button-list
+ (expand-file-name "msg-around.xpm" emchat-glyph-dir))
+ "A send message toolbar icon.")
+
+(defvar emchat-send-url-here-icon
+ (toolbar-make-button-list
+ (expand-file-name "url-here.xpm" emchat-glyph-dir))
+ "A send URL toolbar icon.")
+
+(defvar emchat-send-url-around-icon
+ (toolbar-make-button-list
+ (expand-file-name "url-around.xpm" emchat-glyph-dir))
+ "A send URL toolbar icon.")
+
+(defvar emchat-query-info-here-icon
+ (toolbar-make-button-list
+ (expand-file-name "info-here.xpm" emchat-glyph-dir))
+ "A query info here toolbar icon.")
+
+(defvar emchat-query-info-around-icon
+ (toolbar-make-button-list
+ (expand-file-name "info-around.xpm" emchat-glyph-dir))
+ "A query info here toolbar icon.")
+
+(defvar emchat-update-info-icon
+ (toolbar-make-button-list
+ (expand-file-name "upd-info.xpm" emchat-glyph-dir))
+ "A update info toolbar icon.")
+
+(defvar emchat-search-icon
+ (toolbar-make-button-list
+ (expand-file-name "search.xpm" emchat-glyph-dir))
+ "A search toolbar icon.")
+
+(defvar emchat-authorize-here-icon
+ (toolbar-make-button-list
+ (expand-file-name "auth-here.xpm" emchat-glyph-dir))
+ "A authorize toolbar icon.")
+
+(defvar emchat-login-icon
+ (toolbar-make-button-list
+ (expand-file-name "login.xpm" emchat-glyph-dir))
+ "A login toolbar icon.")
+
+(defvar emchat-logout-icon
+ (toolbar-make-button-list
+ (expand-file-name "logout.xpm" emchat-glyph-dir))
+ "A logout toolbar icon.")
+
+(defvar emchat-exit-icon
+ (toolbar-make-button-list
+ (expand-file-name "exit.xpm" emchat-glyph-dir))
+ "A exit toolbar icon.")
+
+(defvar emchat-new-log-icon
+ (toolbar-make-button-list
+ (expand-file-name "new-log.xpm" emchat-glyph-dir))
+ "New log file toolbar icon.")
+
+(defvar emchat-help-icon
+ (toolbar-make-button-list
+ (expand-file-name "help.xpm" emchat-glyph-dir))
+ "A help toolbar icon.")
+
+;; Define the functions for the toolbar
+
+(defun emchat-toolbar-change-password (password)
+ "Change PASSWORD from the toolbar."
+ (interactive (list (read-passwd "Password: " 'confirm)))
+ (emchat-change-password password))
+
+(defun emchat-toolbar-send-message-here ()
+ "Send message from toolbar."
+ (interactive)
+ (emchat-send-message-alias-here))
+
+(defun emchat-toolbar-send-message-around ()
+ "Send message from toolbar."
+ (interactive)
+ (emchat-send-message))
+
+(defun emchat-toolbar-send-url-here ()
+ "Send URL from the toolbar."
+ (interactive)
+ (emchat-send-url-alias-here))
+
+(defun emchat-toolbar-send-url-around ()
+ "Send URL from the toolbar."
+ (interactive)
+ (emchat-send-url))
+
+(defun emchat-toolbar-query-info-here ()
+ "Query info from the toolbar."
+ (interactive)
+ (emchat-query-info-alias-around))
+
+(defun emchat-toolbar-query-info-around ()
+ "Query info from the toolbar."
+ (interactive)
+ (emchat-query-info))
+
+(defun emchat-toolbar-update-info ()
+ "Update meta info from the toolbar."
+ (interactive)
+ ;(emchat-update-meta-info))
+ (message-or-box "Sorry, this feature is not yet implemented"))
+
+(defun emchat-toolbar-search ()
+ "Search from the toolbar.
+
+Prompts for the search terms."
+ (interactive)
+ (let ((first (read-string "First Name [RET for null]: "))
+ (last (read-string "Last Name [RET for null]: "))
+ (nick (read-string "Nick Name [RET for null]: "))
+ (email (read-string "Email Address [RET for null]: ")))
+ (emchat-search nil first last nick email)))
+
+(defun emchat-toolbar-authorize-here ()
+ "Authorize from the toolbar."
+ (interactive)
+ (emchat-authorize-alias-here))
+
+(defun emchat-toolbar-login ()
+ "Login from the toolbar."
+ (interactive)
+ (emchat-login))
+
+(defun emchat-toolbar-logout ()
+ "Logout from the toolbar."
+ (interactive)
+ (emchat-logout))
+
+(defun emchat-toolbar-exit ()
+ "Exit from the toolbar."
+ (interactive)
+ (emchat-exit))
+
+(defun emchat-toolbar-new-log ()
+ "New log file from the toolbar."
+ (interactive)
+ (emchat-log-new-file))
+
+(defun emchat-toolbar-help ()
+ "Display the EMchat info documentation."
+ (interactive)
+ (Info-goto-node "(emchat.info)Top"))
+
+;; Now define the toolbar
+(defvar emchat-log-toolbar
+ '([emchat-password-icon
+ emchat-toolbar-change-password t "Change password"]
+ [emchat-send-message-here-icon
+ emchat-toolbar-send-message-here t "Send message here"]
+ [emchat-send-message-around-icon
+ emchat-toolbar-send-message-around t "Send message..."]
+ [emchat-send-url-here-icon
+ emchat-toolbar-send-url-here t "Send URL here"]
+ [emchat-send-url-around-icon
+ emchat-toolbar-send-url-around t "Send URL..."]
+ [emchat-query-info-here-icon
+ emchat-toolbar-query-info-here t "Query info here"]
+ [emchat-query-info-around-icon
+ emchat-toolbar-query-info-around t "Query info..."]
+ [emchat-search-icon
+ emchat-toolbar-search t "Search"]
+ [emchat-authorize-here-icon
+ emchat-toolbar-authorize-here t "Authorize here"]
+ [emchat-new-log-icon
+ emchat-toolbar-new-log t "New log file"]
+ [emchat-login-icon
+ emchat-toolbar-login t "Login"]
+ [emchat-logout-icon
+ emchat-toolbar-logout t "Logout"]
+ [emchat-exit-icon
+ emchat-toolbar-exit t "Exit"]
+ nil
+ [emchat-help-icon
+ emchat-toolbar-help t "Help"])
+ "A clickety click EMchat log buffer toolbar.")
+
+;;;###autoload
+(defun emchat-install-buddy-toolbar ()
+ "Install the toolbar for `emchat-buddy-mode' in EMchat."
+ (and emchat-use-toolbar
+ (set-specifier (symbol-value emchat-use-toolbar)
+ (cons
+ (current-buffer) emchat-log-toolbar))))
+
+;;;###autoload
+(defalias 'emchat-install-log-toolbar 'emchat-install-buddy-toolbar)
+
+(provide 'emchat-toolbar)
+
+;;; emchat-toolbar.el ends here
--- /dev/null
+;;; emchat-track.el --- Event tracking code for EMchat.
+
+;; Copyright (C) 2005 - 2007 Steve Youngs, Alexey Mikhailov
+
+;; Author: Alexey Mikhailov <karma@sxemacs.org>
+;; Maintainer: Alexey Mikhailov <karma@sxemacs.org>
+;; Created: 2005-04-25
+;; Homepage: http://www.emchat.org/
+;; Keywords:
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+
+;; emchat-track.el tracks ICQ channel activity and notifies user in modeline.
+;; To start with emchat-track add to your ~/.sxemacs/init.el:
+;;
+;; (require 'emchat-track)
+;; (emchat-track-mode 1)
+;;
+;; or simple:
+;;
+;; (setq emchat-track-enable t)
+;;
+;; if you dont want emchat-track to be loaded
+;;
+;; You may want to customize `emchat-track-events-type' and
+;; `emchat-track-indicator-type'
+
+;;; Code:
+\f
+(eval-when-compile
+ (defvar emchat-log-buffer))
+
+(defgroup emchat-track nil
+ "Track EMchat events and show activity in the modeline."
+ :group 'emchat)
+
+(defcustom emchat-track-enable nil
+ "*Enable tracking."
+ :group 'emchat-track
+ :type 'boolean)
+
+(defcustom emchat-track-events-type 'msg
+ "*What event types to track.
+
+Possible values are:
+ all -- all events \(anything that gets logged will be tracked\)
+ incoming -- only incoming messages plus system and debug events
+ msg -- incoming user messages only
+ nil -- no events."
+ :group 'emchat-track
+ :type '(choice (item :tag "All Events" all)
+ (item :tag "Incoming msg + sys + debug events" incoming)
+ (item :tag "Incoming user messages" msg)
+ (item :tag "Nothing" nil)))
+
+(defcustom emchat-track-indicator-type 'name
+ "*What type of indicator is displayed in the modeline.
+
+Possible values are:
+
+ name -- [nick,nick2,nick3] \(ERC style\).
+ \"nick\" is shortened to `emchat-track-shorten-to'.
+ char -- [E] \(Riece style\)"
+ :type '(radio (item :tag "Multi names \(ERC style\)" name)
+ (item :tag "Single character \(Riece style\)" char))
+ :group 'emchat-track)
+
+(defcustom emchat-track-shorten-to 4
+ "*All nicks will be shortened to this number of chars."
+ :type 'integer
+ :group 'emchat-track)
+
+(defcustom emchat-track-activity-hook nil
+ "*Hooks run when `emchat-track-add-nick' is called."
+ :type 'hook
+ :group 'emchat-track)
+
+(defcustom emchat-track-clear-hook nil
+ "*Hooks run when `emchat-track-clear-modeline' is called."
+ :type 'hook
+ :group 'emchat-track)
+
+;;; Internal variables
+(defvar emchat-track-events-string "")
+
+(defun emchat-track-truncate-nick (nick)
+ "Return shortened nick."
+ (if (> (length nick) emchat-track-shorten-to)
+ (substring nick 0 emchat-track-shorten-to)
+ nick))
+
+(defun emchat-track-add-nick (nick)
+ "Add new nick to events strings."
+ (let ((snick (emchat-track-truncate-nick nick)))
+ (setq global-mode-string
+ (delq 'emchat-track-events-string global-mode-string))
+ (if (eq emchat-track-indicator-type 'char)
+ ;; Riece style indicator.
+ (setq emchat-track-events-string "[E]")
+ ;; ERC style indicator.
+ (if (equal emchat-track-events-string "")
+ (setq emchat-track-events-string (format "[%s]" snick))
+ (and (not (search snick emchat-track-events-string))
+ (setq emchat-track-events-string
+ (format "%s,%s]"
+ (substring emchat-track-events-string 0
+ (1- (length emchat-track-events-string)))
+ snick)))))
+ (setq global-mode-string (append global-mode-string
+ '(emchat-track-events-string)))
+ (run-hooks 'emchat-track-activity-hook)
+ (redraw-modeline t)))
+
+(defun emchat-track-clear-modeline ()
+ "Remove `emchat-track' messages from modeline."
+ (setq global-mode-string (delq 'emchat-track-events-string global-mode-string))
+ (setq emchat-track-events-string "")
+ (run-hooks 'emchat-track-clear-hook)
+ (redraw-modeline t))
+
+(defun emchat-track-check-log-buffer ()
+ (and (get-buffer-window emchat-log-buffer)
+ (emchat-track-clear-modeline)))
+
+(defun emchat-track-init ()
+ "Initialize `emchat-track', perform defadvices and hooks"
+ (defadvice switch-to-buffer (after emchat-update (&rest args) activate)
+ "After switching buffers, check to see if emchat-track should be cleared.
+The emchat-track modeline indicator will only be cleared if
+`emchat-log-buffer' is visible in the selected frame."
+ (emchat-track-check-log-buffer))
+ (add-hook 'select-frame-hook 'emchat-track-check-log-buffer)
+ (put 'emchat-track 'initialized t))
+
+(defun emchat-track-mode (&optional arg)
+ "Toggle emchat track mode."
+ (interactive "P")
+ (if (or (and (numberp arg) (< arg 0))
+ (and (null arg) emchat-track-enable))
+ (setq emchat-track-enable nil)
+ (setq emchat-track-enable t)))
+
+(defun emchat-track-enable ()
+ (interactive)
+ (emchat-track-mode 1))
+
+(defun emchat-track-disable ()
+ (interactive)
+ (emchat-track-mode -1))
+
+(provide 'emchat-track)
+;;; emchat-track.el ends here
--- /dev/null
+;; emchat-utils.el --- misc utils for EMchat -*- Emacs-Lisp -*-
+
+;; Copyright (C) 2007 Steve Youngs
+
+;; Author: Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created: <2007-09-01>
+;; Homepage: http://www.emchat.org/
+;; Keywords: utils ICQ emchat
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+;; This is where any general-purpose utils for EMchat go
+
+;;; Code:
+(eval-when-compile
+ (defvar emchat-all-aliases))
+
+(defcustom emchat-glyph-dir
+ (file-name-as-directory (or (locate-data-directory "emchat") ""))
+ "Directory where icons and logos live."
+ :type 'directory
+ :group 'emchat-interface)
+
+;;; Internal variables
+
+(defmacro emchat-do-in-xemacs (&rest body)
+ "Execute BODY if in XEmacs."
+ (when (featurep '(and xemacs (not sxemacs)))
+ `(progn ,@body)))
+
+(put 'emchat-do-in-xemacs 'lisp-indent-hook 'defun)
+
+(defmacro emchat-do-in-sxemacs (&rest body)
+ "Execute BODY if in SXEmacs."
+ (when (featurep 'sxemacs)
+ `(progn ,@body)))
+
+(put 'emchat-do-in-sxemacs 'lisp-indent-hook 'defun)
+
+(defun emchat-completing-read
+ (prompt table &optional predicate require-match initial-contents history)
+ "Args: PROMPT, TABLE, PREDICATE, REQUIRE-MATCH, INITIAL-CONTENTS, HISTORY.
+Same as `completing-read' but accepts strings as well as obarray."
+ (completing-read
+ prompt
+ (if (vectorp table)
+ table (mapcar 'list table))
+ predicate require-match initial-contents history))
+
+(defun emchat-numeric-uin (uin)
+ "Return UIN as number.
+UIN can be either a string or number."
+ (cond ((numberp uin) uin)
+ ((stringp uin) (string-to-number uin))
+ (t (error "Invalid UIN type" uin))))
+
+(defun emchat-stringular-uin (uin)
+ "Return UIN as a string.
+UIN can be either a string or a number."
+ (cond ((numberp uin) (number-to-string uin))
+ ((stringp uin) uin)
+ (t (error "Invalid UIN type" uin))))
+
+(defun emchat-valid-uin-p (uin)
+ "Return non-nil if UIN is a valid uin."
+ (not (zerop (emchat-numeric-uin uin))))
+
+(defun emchat-completing-aliases (prompt &optional single)
+ "Completing-read aliases/uin.
+PROMPT is the prompt for reading.
+SINGLE means read only one alias/uin.
+
+Must at least complete one alias, use RET (empty string) to finish
+entering. It first completing-reads from the union of `emchat-active-aliases'
+and `emchat-connected-aliases'. If you hit RET and the input string is not in
+the union it the completing-reads from `emchat-all-aliases'.
+
+Tips: You can also enter an uin in place of an alias."
+ (let ((aliases
+ ;; a must for first one
+ (cons (emchat-completing-alias prompt 'required)
+ (unless single
+ (loop collect (emchat-completing-alias prompt nil)
+ into aliases
+ ;; empty string means abort
+ until (string= (car (last aliases)) "")
+ finally return (nbutlast aliases))))))
+ (delete-duplicates aliases :test 'string=)))
+
+(defun emchat-completing-alias (prompt required)
+ "Completing only one alias/uin.
+PROMPT is the prompt for reading.
+REQUIRED means cannot abort.
+Used by `emchat-completing-aliases'.
+No abortion when `** ' is in prompt.
+Abort by RET (empty string) when `++ ' is in prompt."
+ (let ((all emchat-all-aliases)
+ (alias
+ (emchat-completing-read
+ prompt
+ emchat-all-aliases
+ nil nil nil 'emchat-alias-history)))
+ (unless (or
+ ;; valid alias
+ (member alias all)
+ ;; valid uin
+ (emchat-valid-uin-p alias)
+ ;; abort
+ (and (string= alias "")
+ (not required)))
+ (loop do
+ (setq alias
+ (emchat-completing-read
+ (concat (if required "** " "++ ") prompt)
+ all nil t alias 'emchat-alias-history))
+ while (and (string= alias "") required)))
+ alias))
+
+(defun emchat-switch-buffer (buffer)
+ (when buffer
+ (select-window (get-buffer-window buffer))))
+
+
+
+(provide 'emchat-utils)
+;;; emchat-utils.el ends here
--- /dev/null
+;;; emchat-v8.el --- ICQ v8 for emchat.
+
+;; Copyright (C) 2004 - 2008 Steve Youngs, Zajcev Evgeny
+
+;; Author: Zajcev Evgeny <zevlg@yandex.ru>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created: Mon Jun 7 16:20:56 MSD 2004
+;; Keywords: emchat ICQ protocol
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+
+;; Testing UIN: 286012066, PASS: 123
+;; UIN: 321529598, PASS: 123
+;;
+;; The various network packets that make up the ICQv8 protocol.
+;;
+;; See: <http://www.emchat.org/~steve/icq/docs/>
+;; <http://iserverd1.khstu.ru/oscar/index.html>
+
+;;; Code:
+\f
+(eval-when-compile
+ (require 'cl)
+ (defvar emchat-add-user-success))
+
+;;;; Constants
+
+;; FLAP channel ids
+(defconst emchat-v8-FLAP-HELLO 1)
+(defconst emchat-v8-FLAP-SNAC 2)
+(defconst emchat-v8-FLAP-ERRORS 3)
+(defconst emchat-v8-FLAP-LOGOFF 4)
+(defconst emchat-v8-FLAP-PING 5)
+
+(defconst emchat-v8-client-id-string
+ "ICQ Inc. - Product of ICQ (TM).2002a.5.37.1.3728.85"
+ "A string to identify ourselves as a nice well behaved ICQ client.")
+
+(defconst emchat-v8-FLAP-VER-MAJOR 5)
+(defconst emchat-v8-FLAP-VER-MINOR 37)
+(defconst emchat-v8-FLAP-VER-LESSER 1)
+(defconst emchat-v8-FLAP-VER-BUILD 3828)
+(defconst emchat-v8-FLAP-VER-SUBBUILD 85)
+
+(defconst emchat-v8-message-types
+ '(normal
+ chat-request
+ url
+ request-auth
+ authorize
+ added
+ pager
+ email-express
+ email-check
+ card
+ contact-list)
+ "List of valid message types.")
+
+(defconst emchat-v8-valid-incoming-handlers
+ '(connected ; args: no
+ disconnected ; args: no
+ instant-message ; args: uin, msg &optional msg-type, time-stamp
+ offline-message ; args: uin, msg &optional msg-type, time-stamp
+ end-offline-messages ;
+ about-general ; general info about user
+ about-more
+ about-about
+ srv-error
+ ;; TODO: add more
+ )
+ "List of valid incoming message handlers.
+
+To bind on to handle incoming part of icq v8 proto.")
+
+(defconst emchat-v8-valid-outgoing-handlers
+ '(
+ ;; TODO: add some handlers
+ )
+ "List of valid outgoing message handlers.
+
+To bind on to handle outgoing part of icq v8 proto.")
+
+(defstruct emchat-v8-ctx
+ host port ; host/port we are currently connected
+ proc ; emchat network connection
+ (readingp 0) ; non-0 if we are currently reading from emchat context
+ sequence ; current flap sequence
+
+ incoming-buffer ; where incoming data stored
+ incoming-handlers
+ outgoing-buffer ; buffer for outgoing messages
+ outgoing-handles
+
+ state ; current state, connecting, connected
+ userinfo ; plist of userinfo '(uin <num> password <passwd>)
+ plist ; user defined plist
+ )
+
+(defun emchat-v8-ctx-get-prop (ectx prop)
+ "Get ECTX's property PROP value."
+ (plist-get (emchat-v8-ctx-plist ectx) prop))
+
+(defun emchat-v8-ctx-put-prop (ectx prop val)
+ "Put ECTX's property PROP value VAL."
+ (setf (emchat-v8-ctx-plist ectx)
+ (plist-put (emchat-v8-ctx-plist ectx) prop val)))
+(put 'emchat-v8-ctx-put-prop 'lisp-indent-function 2)
+
+(defun emchat-v8-ctx-rm-prop (ectx prop)
+ "Remove ECTX's property PROP."
+ (setf (emchat-v8-ctx-plist ectx)
+ (plist-remprop (emchat-v8-ctx-plist ectx) prop)))
+
+(defun emchat-v8-ctx-get-incoming-handlers (ectx h)
+ (plist-get (emchat-v8-ctx-incoming-handlers ectx) h))
+
+(defun emchat-v8-ctx-add-incoming-handler (ectx h f)
+ (setf (emchat-v8-ctx-incoming-handlers ectx)
+ (plist-put (emchat-v8-ctx-incoming-handlers ectx) h
+ (cons f (emchat-v8-ctx-get-incoming-handlers ectx h)))))
+
+(defun emchat-v8-ctx-del-incoming-handler (ectx h f)
+ (setf (emchat-v8-ctx-incoming-handlers ectx)
+ (plist-put (emchat-v8-ctx-incoming-handlers ectx) h
+ (delete f (emchat-v8-ctx-get-incoming-handlers ectx h)))))
+
+(defun emchat-v8-ctx-run-incoming-handler (ectx h &rest args)
+ (let ((ohs (emchat-v8-ctx-get-incoming-handlers ectx h))
+ (ih-arguments args))
+ (when ohs
+ (declare (special ih-arguments))
+ (apply 'run-hook-with-args (cons 'ohs (cons ectx args))))))
+(put 'emchat-v8-ctx-run-incoming-handler 'lisp-indent-function 2)
+
+(defun emchat-get-arg (kw)
+ (declare (special ih-arguments))
+ (plist-get ih-arguments kw))
+
+\f
+(defmacro emchat-v8-ctx-msg-to-send (ectx)
+ `(emchat-v8-ctx-get-prop ,ectx 'message-to-send))
+(defsetf emchat-v8-ctx-msg-to-send (ectx) (msg)
+ `(emchat-v8-ctx-put-prop ,ectx 'message-to-send ,msg))
+
+(defmacro emchat-v8-ctx-pause-p (ectx)
+ `(emchat-v8-ctx-get-prop ,ectx 'pause-p))
+(defsetf emchat-v8-ctx-pause-p (ectx) (pp)
+ `(if ,pp
+ (progn
+ (emchat-v8-ctx-put-prop ,ectx 'pause-p ,pp)
+ (setf (emchat-v8-ctx-msg-to-send ,ectx) ""))
+ (emchat-v8-ctx-rm-prop ,ectx 'pause-p)
+ (emchat-v8-send ,ectx (emchat-v8-ctx-msg-to-send ,ectx))
+ (setf (emchat-v8-ctx-msg-to-send ,ectx) "")))
+
+\f
+(defvar emchat-v8-default-ctx nil
+ "Internal variable, do not modify.")
+
+(defvar emchat-v8-connections nil
+ "List if emchat connections.
+Internal variable, do not modify.")
+
+(defcustom emchat-v8-debug t
+ "*Non-nil mean emchat protocol debugging is enabled."
+ :type 'boolean)
+
+\f
+(defvar emchat-debug-buffer "*emchat-debug*")
+
+(defun emchat-v8-debug (msg &rest args)
+ "Print debug MSG."
+ (when emchat-v8-debug
+ (with-current-buffer
+ (get-buffer-create emchat-debug-buffer)
+ (save-excursion
+ (goto-char (point-max))
+ (insert (apply 'format msg args) "\n")))))
+
+(defun emchat-v8-ctx ()
+ "Return default EMchat context."
+ emchat-v8-default-ctx)
+
+;; FLAP accessors
+(defsubst emchat-v8-flap-cid (flap)
+ (nth 0 flap))
+(defsubst emchat-v8-flap-seq (flap)
+ (nth 1 flap))
+(defsubst emchat-v8-flap-data (flap)
+ (nth 2 flap))
+
+;;; SNAC accessors
+(defsubst emchat-v8-snac-family (snac)
+ (nth 0 snac))
+(defsubst emchat-v8-snac-subtype (snac)
+ (nth 1 snac))
+(defsubst emchat-v8-snac-flags (snac)
+ (nth 2 snac))
+(defsubst emchat-v8-snac-rid (snac)
+ (nth 3 snac))
+
+;;; TLV accessors
+(defsubst emchat-v8-tlv-type (tlv)
+ (nth 0 tlv))
+(defsubst emchat-v8-tlv-len (tlv)
+ (nth 1 tlv))
+(defsubst emchat-v8-tlv-val (tlv)
+ (nth 2 tlv))
+(defsubst emchat-v8-tlv-str (tlv)
+ (aref (emchat-v8-tlv-val tlv) 0))
+(defsubst emchat-v8-tlv-num (tlv)
+ (truncate (emchat-v8-string->number
+ (aref (emchat-v8-tlv-val tlv) 0) (truncate (emchat-v8-tlv-len tlv)))))
+
+(defun emchat-v8-util-encrypt (password)
+ (let ((tb "\xf3\x26\x81\xc4\x39\x86\xdb\x92\x71\xa3\xb9\xe6\x53\x7a\x95\x7c")
+ (res (make-string (length password) ?\x00))
+ (idx 0))
+ (while (< idx (length password))
+ (aset res idx (logxor (aref password idx) (aref tb (mod idx 16))))
+ (setq idx (1+ idx)))
+ res))
+
+(defun emchat-v8-create-ctx (uin &optional password &rest plist)
+ "Create new emchat context using UIN/PASSWORD.
+PLIST is ectx properties list"
+ (let ((ectx (make-emchat-v8-ctx :state 'disconnected :plist plist)))
+ (setf (emchat-v8-ctx-userinfo ectx)
+ (list 'uin uin 'password password))
+ ectx))
+
+(defun emchat-v8-connect (ectx &optional server port)
+ "Connect to SERVER and PORT."
+ (unless server
+ (setq server (or (emchat-v8-ctx-host ectx) "login.icq.com")))
+ (unless port
+ (setq port (or (emchat-v8-ctx-host ectx) 5190)))
+
+ (setf (emchat-v8-ctx-host ectx) server)
+ (setf (emchat-v8-ctx-port ectx) port)
+
+ (let* ((proc (open-network-stream (format "emchat-v8-%s:%d" server port) nil
+ server port))
+ (state (emchat-v8-ctx-state ectx)))
+
+ (setf (emchat-v8-ctx-proc ectx) proc)
+ (setf (emchat-v8-ctx-sequence ectx) (random 65536))
+
+ ;; Store connection in emchat connections list
+ (push ectx emchat-v8-connections)
+
+ (set-process-filter proc 'emchat-v8-proc-filter-proccessing)
+ (set-process-sentinel proc 'emchat-v8-proc-sentinel)
+
+ (emchat-v8-debug "Connecting from state=%S" (emchat-v8-ctx-state ectx))
+
+ ;; Adjust ECTX state
+ (cond ((or (eq state 'connecting)
+ (eq state 'closed))
+ (setf (emchat-v8-ctx-state ectx) 'connected))
+ (t (setf (emchat-v8-ctx-state ectx) 'connecting)))
+ ectx))
+
+(defun emchat-v8-close (ectx)
+ "Close ECTX connection."
+ (setf (emchat-v8-ctx-state ectx) 'closed)
+ (emchat-v8-proc-sentinel (emchat-v8-ctx-proc ectx)))
+
+(defun emchat-v8-send (ectx msg)
+ "Using emchat context ECTX, send message MSG."
+ (if (not (emchat-v8-ctx-pause-p ectx))
+ (process-send-string (emchat-v8-ctx-proc ectx) msg)
+ ;; Add MSG to the pending data pending
+ (setf (emchat-v8-ctx-msg-to-send ectx)
+ (concat (emchat-v8-ctx-msg-to-send ectx) msg))))
+(put 'emchat-v8-send 'lisp-indent-function 1)
+
+(defun emchat-v8-send-flush (ectx)
+ "Flush ECTX's output buffer."
+ (when (> (length (emchat-v8-ctx-outgoing-buffer ectx)) 0)
+ (process-send-string
+ (emchat-v8-ctx-proc ectx)
+ (emchat-v8-ctx-outgoing-buffer ectx))))
+
+(defun emchat-v8-proc-find (proc)
+ "Find emchat context by PROC."
+ (let ((ecs emchat-v8-connections))
+ (while (and ecs (not (eq (emchat-v8-ctx-proc (car ecs)) proc)))
+ (setq ecs (cdr ecs)))
+ (car ecs)))
+
+(defun emchat-v8-proc-sentinel (proc &optional event)
+ "Sentinel for emchat PROC."
+ (let ((ectx (emchat-v8-proc-find proc)))
+ (when (emchat-v8-ctx-p ectx)
+
+ (emchat-v8-debug "Removing process %S, state=%S, c-t=%S"
+ proc (emchat-v8-ctx-state ectx) (emchat-v8-ctx-get-prop ectx 'connect-tries))
+ (delete-process proc)
+ (setf (emchat-v8-ctx-incoming-buffer ectx) "") ;flush input buffer
+
+ (setq emchat-v8-connections (delq ectx emchat-v8-connections))
+ (when (eq (emchat-v8-ctx-state ectx) 'connected)
+ ;; Unexpected disconnection
+ (emchat-v8-ctx-run-incoming-handler ectx 'disconnect)))))
+
+(defun emchat-v8-proc-filter-accumulator (proc out)
+ "Filter for emchat connection to accumulate data."
+ (let ((ectx (emchat-v8-proc-find proc)))
+ (when (emchat-v8-ctx-p ectx)
+ (setf (emchat-v8-ctx-incoming-buffer ectx)
+ (concat (emchat-v8-ctx-incoming-buffer ectx) out)))))
+
+(defun emchat-v8-proc-filter-proccessing (proc out)
+ "Filter for emchat connection."
+ (let ((ectx (emchat-v8-proc-find proc)))
+ (when (emchat-v8-ctx-p ectx)
+ (setf (emchat-v8-ctx-incoming-buffer ectx)
+ (concat (emchat-v8-ctx-incoming-buffer ectx) out))
+ (enqueue-eval-event 'emchat-v8-fetch-handle-flaps ectx))))
+
+(defvar emchat-v8-snacv-list
+ '((#x01 . #x04)
+ (#x13 . #x04)
+ (#x02 . #x01)
+ (#x03 . #x01)
+ (#x15 . #x01)
+ (#x04 . #x01)
+ (#x06 . #x01)
+ (#x09 . #x01)
+ (#x0A . #x01)
+ (#x0B . #x01)))
+
+(defconst emchat-v8-snac-list
+ '(
+ ;; Family 1, Service
+ ((#x01 . #x01) "SRV_GEN_ERROR" emchat-v8-snac-srv-err)
+ ((#x01 . #x02) "CLI_READY" nil)
+ ((#x01 . #x03) "SRV_FAMILIES" emchat-v8-snac-srv-families)
+ ((#x01 . #x06) "CLI_RATESREQUEST" emchat-v8-snac-cli-ratesrequest)
+ ((#x01 . #x07) "SRV_RATES" emchat-v8-snac-srv-rates)
+ ;((#x01 . #x08) "CLI_ACKRATES" nil) ; handled in SRV_RATES
+ ((#x01 . #x0A) "SRV_RATE_CHANGE" emchat-v8-snac-srv-rate-change)
+ ((#x01 . #x0B) "SRV_SERVERPAUSE" emchat-v8-snac-srv-pause)
+ ((#x01 . #x0C) "CLI_ACKSERVERPAUSE" nil)
+ ((#x01 . #x0E) "CLI_REQINFO" nil)
+ ((#x01 . #x0F) "SRV_REPLYINFO" emchat-v8-snac-srv-replyinfo)
+ ((#x01 . #x12) "SRV_MIGRATIONREQ" emchat-v8-snac-srv-migrate)
+ ((#x01 . #x13) "SRV_MOTD" emchat-v8-snac-srv-motd)
+ ((#x01 . #x17) "CLI_FAMILIES" nil)
+ ((#x01 . #x18) "SRV_FAMILIES2" emchat-v8-snac-srv-families2)
+ ((#x01 . #x1E) "CLI_SETSTATUS" nil)
+ ((#x01 . #x21) "BART_REQUEST" emchat-v8-snac-bart-request)
+ ;; Family 2, Location
+ ((#x02 . #x01) "SRV_GEN_ERROR" emchat-v8-snac-srv-err)
+ ((#x02 . #x02) "CLI_REQLOCATION" nil)
+ ((#x02 . #x03) "SRV_REPLYLOCATION" emchat-v8-snac-srv-reply-location)
+ ((#x02 . #x04) "CLI_SETUSERINFO" nil)
+ ;; Family 3, Buddy lists (looks like AOL has turned this off)
+ ((#x03 . #x01) "SRV_CONTACTERR" emchat-v8-snac-srv-contact-err)
+ ((#x03 . #x02) "CLI_REQBUDDY" nil)
+ ((#x03 . #x03) "SRV_REPLYBUDDY" emchat-v8-snac-srv-reply-buddy)
+ ((#x03 . #x04) "CLI_ADDCONTACT" nil)
+ ((#x03 . #x05) "CLI_REMCONTACT" nil)
+ ((#x03 . #x0A) "SRV_REFUSE" emchat-v8-snac-srv-cont-refused)
+ ((#x03 . #x0B) "SRV_USERONLINE" emchat-v8-snac-srv-user-online)
+ ((#x03 . #x0C) "SRV_USEROFFLINE" emchat-v8-snac-srv-user-offline)
+ ;; Family 4, ICBM
+ ((#x04 . #x01) "SRV_ICBMERR" emchat-v8-snac-srv-icbm-err)
+ ((#x04 . #x02) "CLI_SETICBM" nil)
+ ((#x04 . #x04) "CLI_REQICBM" nil)
+ ((#x04 . #x05) "SRV_REPLYICBM" emchat-v8-snac-srv-reply-icbm)
+ ((#x04 . #x06) "CLI_SENDMSG" nil)
+ ((#x04 . #x07) "SRV_RECVMSG" emchat-v8-snac-srv-recv-msg)
+ ((#x04 . #x0A) "SRV_MISSED_ICBM" emchat-v8-snac-srv-missed-icbm)
+ ((#x04 . #x0B) "SRV/CLI_ACKMSG" emchat-v8-snac-srv-ack-msg)
+ ((#x04 . #x0C) "SRV_SRVACKMSG" emchat-v8-snac-srv-srv-ack-msg)
+ ;; Family 5, Advertising NOT USED (thank god!)
+ ;; Family 6, Invitation (Invite somebody to AIM) erm, EMchat won't!!
+ ;; Family 7, Admin (AIM)
+ ;; Family 8, Popup Notices (AIM)
+ ;; Family 9, Privacy
+ ((#x09 . #x01) "SRV_GEN_ERROR" emchat-v8-snac-srv-err)
+ ((#x09 . #x02) "CLI_REQBOS" nil)
+ ((#x09 . #x03) "SRV_REPLYBOS" emchat-v8-snac-srv-reply-bos)
+ ((#x09 . #x05) "CLI_ADDVISIBLE" emchat-v8-snac-cli-addvisible)
+ ((#x09 . #x06) "CLI_REMVISIBLE" emchat-v8-snac-cli-remvisible)
+ ((#x09 . #x07) "CLI_ADDINVISIBLE" emchat-v8-snac-cli-addinvisible)
+ ((#x09 . #x08) "CLI_REMINVISIBLE" emchat-v8-snac-cli-reminvisible)
+ ;; Family a [10], User Lookup (AIM and no longer used)
+ ;; Family b [11], Usage Stats Interval
+ ((#x0B . #x01) "SRV_GEN_ERROR" emchat-v8-snac-srv-err)
+ ((#x0B . #x02) "SRV_SETINTERVAL" emchat-v8-snac-srv-set-interval)
+ ;; Family c [12], Translation Service (deprecated (AIM))
+ ;; Family d [13], Chat Navigation (AIM)
+ ;; Family e [14], Chat Service (AIM)
+ ;; Family f [15], Directory Search (AIM)
+ ;; Family 10 [16], Server Stored Buddy Icons
+ ;; Family 13 [19], Server Side Info
+ ((#x13 . #x01) "SRV_GEN_ERROR" emchat-v8-snac-srv-err)
+ ((#x13 . #x02) "CLI_SSI_RIGHTS_REQUEST" emchat-v8-snac-cli-ssi-right-request)
+ ((#x13 . #x03) "SRV_SSI_RIGHTS_REPLY" emchat-v8-snac-srv-ssi-rights-reply)
+ ((#x13 . #x04) "CLI_SSI_REQUEST" emchat-v8-snac-cli-ssi-request)
+ ((#x13 . #x05) "CLI_SSI_CHECKOUT" emchat-v8-snac-cli-ssi-checkout)
+ ((#x13 . #x06) "SRV_SSI_REPLY" emchat-v8-snac-srv-ssi-reply)
+ ((#x13 . #x07) "CLI_SSI_ACTIVATE" emchat-v8-snac-cli-ssi-activate)
+ ((#x13 . #x08) "CLI_SSI_ADD" emchat-v8-snac-cli-ssi-add) ; broken
+ ((#x13 . #x09) "CLI_SSI_UPDATE" emchat-v8-snac-cli-ssi-update) ; not implimented yet
+ ((#x13 . #x0A) "CLI_SSI_DELETE" emchat-v8-snac-cli-ssi-delete) ; not implimented yet
+ ((#x13 . #x0E) "SRV_SSI_MOD_ACK" emchat-v8-snac-srv-ssi-mod-ack)
+ ((#x13 . #x0F) "SRV_SSI_UP_TO_DATE" emchat-v8-snac-srv-ssi-up-to-date)
+ ((#x13 . #x11) "CLI_SSI_EDIT_BEGIN" emchat-v8-snac-cli-ssi-edit-begin)
+ ((#x13 . #x12) "CLI_SSI_EDIT_END" emchat-v8-snac-cli-ssi-edit-end)
+ ((#x13 . #x14) "CLI_SSI_FUTURE_AUTH_GRANT" emchat-v8-snac-cli-ssi-future-auth-grant)
+ ((#x13 . #x15) "SRV_SSI_FUTURE_AUTH_GRANTED" emchat-v8-snac-srv-ssi-future-auth-granted)
+ ((#x13 . #x16) "CLI_SSI_DEL_YOURSELF" emchat-v8-snac-cli-ssi-del-yourself)
+ ((#x13 . #x18) "CLI_SSI_SEND_AUTH_REQUEST" emchat-v8-snac-cli-ssi-send-auth-request)
+ ((#x13 . #x19) "SRV_SSI_AUTH_REQUEST" emchat-v8-snac-srv-ssi-auth-request)
+ ((#x13 . #x1A) "CLI_SSI_AUTH_REPLY" emchat-v8-snac-cli-ssi-auth-reply)
+ ((#x13 . #x1B) "SRV_SSI_AUTH_REPLY" emchat-v8-snac-srv-ssi-auth-reply)
+ ((#x13 . #x1C) "SRV_SSI_YOU_WERE_ADDED" emchat-v8-snac-srv-ssi-you-were-added)
+ ;; Family 15 [21], ICQ Specific
+ ((#x15 . #x01) "SRV_TOICQERR" emchat-v8-snac-srv-toicqerr)
+ ;; This is like a family within a family... all the SNACS are #x15,#x02
+ ;; but they also have types and subtypes to differentiate between them.
+ ;; So we really don't need a function here.
+ ((#x15 . #x02) "CLI_TOICQSRV" nil)
+ ((#x15 . #x03) "SRV_FROMICQSRV" emchat-v8-snac-srv-fromicqsrv)
+ ;; Family 17 [23], Authorisation/Registration
+ ((#x17 . #x01) "SRV_REGREFUSED" emchat-v8-snac-srv-regrefused)
+ ((#x17 . #x05) "SRV_NEWUIN" emchat-v8-snac-srv-newuin)
+ ((#x17 . #x04) "CLI_REGISTERUSER" nil)
+
+ ((0 . 0) "unknown" nil))
+ "List of SNAC specs.")
+
+(defun emchat-v8-recv-message (ectx h-type data)
+ "Receive message."
+ (let* ((uin (emchat-v8-fetch-uin data))
+ (msg (emchat-v8-parse-message data
+ (list [2 number-swap] ;year
+ [1 number] ;month
+ [1 number] ;day
+ [1 number] ;hour
+ [1 number] ;minutes
+ )))
+ (tmsg (emchat-v8-parse-message data
+ (list [2 number-swap]
+ [2 number])))
+ (ctext (substring (aref data 0) 0 (1- (length (aref data 0)))))
+ (time-stamp (list (truncate (nth 0 msg))
+ (truncate (nth 1 msg))
+ (truncate (nth 2 msg))
+ (truncate (nth 3 msg))
+ (truncate (nth 4 msg)))))
+
+ (emchat-v8-debug "Recv-message: '%S', tmsg='%S'" ctext tmsg)
+
+ ;; XXX 'normal
+ (emchat-v8-ctx-run-incoming-handler ectx h-type
+ :uin uin :msg ctext :msg-type 'normal :time-stamp time-stamp)))
+
+(defmacro emchat-v8-get-alist-value (code alist)
+ `(cdr (assq ,code ,alist)))
+
+(defconst emchat-v8-countries-alist
+ '((0 . "Undefined")
+ (1 . "USA")
+ (101 . "Anguilla")
+ (102 . "Antigua")
+ (1021 . "Antigua & Barbuda")
+ (103 . "Bahamas")
+ (104 . "Barbados")
+ (105 . "Bermuda")
+ (106 . "British Virgin Islands")
+ (107 . "Canada")
+ (108 . "Cayman Islands")
+ (109 . "Dominica")
+ (110 . "Dominican Republic")
+ (111 . "Grenada")
+ (112 . "Jamaica")
+ (113 . "Montserrat")
+ (114 . "Nevis")
+ (1141 . "Saint Kitts and Nevis")
+ (115 . "St. Kitts")
+ (116 . "St. Vincent & the Grenadines")
+ (117 . "Trinidad & Tobago")
+ (118 . "Turks & Caicos Islands")
+ (120 . "Barbuda")
+ (121 . "Puerto Rico")
+ (122 . "Saint Lucia")
+ (123 . "Virgin Islands (USA)")
+ (178 . "Canary Islands")
+ (20 . "Egypt")
+ (212 . "Morocco")
+ (213 . "Algeria")
+ (216 . "Tunisia")
+ (218 . "Libyan Arab Jamahiriya")
+ (220 . "Gambia")
+ (221 . "Senegal")
+ (222 . "Mauritania")
+ (223 . "Mali")
+ (224 . "Guinea")
+ (225 . "Cote d'Ivoire")
+ (226 . "Burkina Faso")
+ (227 . "Niger")
+ (228 . "Togo")
+ (229 . "Benin")
+ (230 . "Mauritius")
+ (231 . "Liberia")
+ (232 . "Sierra Leone")
+ (233 . "Ghana")
+ (234 . "Nigeria")
+ (235 . "Chad")
+ (236 . "Central African Republic")
+ (237 . "Cameroon")
+ (238 . "Cape Verde Islands")
+ (239 . "Sao Tome & Principe")
+ (240 . "Equatorial Guinea")
+ (241 . "Gabon")
+ (242 . "Congo, (Rep. of the)")
+ (243 . "Congo, Democratic Republic of")
+ (244 . "Angola")
+ (245 . "Guinea-Bissau")
+ (246 . "Diego Garcia")
+ (247 . "Ascension Island")
+ (248 . "Seychelles")
+ (249 . "Sudan")
+ (250 . "Rwanda")
+ (251 . "Ethiopia")
+ (252 . "Somalia")
+ (253 . "Djibouti")
+ (254 . "Kenya")
+ (255 . "Tanzania")
+ (256 . "Uganda")
+ (257 . "Burundi")
+ (258 . "Mozambique")
+ (260 . "Zambia")
+ (261 . "Madagascar")
+ (262 . "Reunion Island")
+ (263 . "Zimbabwe")
+ (264 . "Namibia")
+ (265 . "Malawi")
+ (266 . "Lesotho")
+ (267 . "Botswana")
+ (268 . "Swaziland")
+ (269 . "Mayotte Island")
+ (2691 . "Comoros")
+ (27 . "South Africa")
+ (290 . "St. Helena")
+ (291 . "Eritrea")
+ (297 . "Aruba")
+ (298 . "Faeroe Islands")
+ (299 . "Greenland")
+ (30 . "Greece")
+ (31 . "Netherlands")
+ (32 . "Belgium")
+ (33 . "France")
+ (34 . "Spain")
+ (350 . "Gibraltar")
+ (351 . "Portugal")
+ (352 . "Luxembourg")
+ (353 . "Ireland")
+ (354 . "Iceland")
+ (355 . "Albania")
+ (356 . "Malta")
+ (357 . "Cyprus")
+ (358 . "Finland")
+ (359 . "Bulgaria")
+ (36 . "Hungary")
+ (370 . "Lithuania")
+ (371 . "Latvia")
+ (372 . "Estonia")
+ (373 . "Moldova, Republic of")
+ (374 . "Armenia")
+ (375 . "Belarus")
+ (376 . "Andorra")
+ (377 . "Monaco")
+ (378 . "San Marino")
+ (379 . "Vatican City")
+ (380 . "Ukraine")
+ (381 . "Yugoslavia")
+ (3811 . "Yugoslavia - Serbia")
+ (382 . "Yugoslavia - Montenegro")
+ (385 . "Croatia")
+ (386 . "Slovenia")
+ (387 . "Bosnia & Herzegovina")
+ (389 . "Macedonia (F.Y.R.O.M.)")
+ (39 . "Italy")
+ (40 . "Romania")
+ (41 . "Switzerland")
+ (4101 . "Liechtenstein")
+ (42 . "Czech Republic")
+ (4201 . "Slovakia")
+ (43 . "Austria")
+ (44 . "United Kingdom")
+ (441 . "Wales")
+ (442 . "Scotland")
+ (45 . "Denmark")
+ (46 . "Sweden")
+ (47 . "Norway")
+ (48 . "Poland")
+ (49 . "Germany")
+ (500 . "Falkland Islands")
+ (501 . "Belize")
+ (502 . "Guatemala")
+ (503 . "El Salvador")
+ (504 . "Honduras")
+ (505 . "Nicaragua")
+ (506 . "Costa Rica")
+ (507 . "Panama")
+ (508 . "St. Pierre & Miquelon")
+ (509 . "Haiti")
+ (51 . "Peru")
+ (52 . "Mexico")
+ (53 . "Cuba")
+ (54 . "Argentina")
+ (55 . "Brazil")
+ (56 . "Chile, Republic of")
+ (57 . "Colombia")
+ (58 . "Venezuela")
+ (590 . "Guadeloupe")
+ (5901 . "French Antilles")
+ (5902 . "Antilles")
+ (591 . "Bolivia")
+ (592 . "Guyana")
+ (593 . "Ecuador")
+ (594 . "French Guyana")
+ (595 . "Paraguay")
+ (596 . "Martinique")
+ (597 . "Suriname")
+ (598 . "Uruguay")
+ (599 . "Netherlands Antilles")
+ (60 . "Malaysia")
+ (61 . "Australia")
+ (6101 . "Cocos-Keeling Islands")
+ (6102 . "Cocos (Keeling) Islands")
+ (62 . "Indonesia")
+ (63 . "Philippines")
+ (64 . "New Zealand")
+ (65 . "Singapore")
+ (66 . "Thailand")
+ (670 . "Saipan Island")
+ (6701 . "Rota Island")
+ (6702 . "Tinian Island")
+ (671 . "Guam, US Territory of")
+ (672 . "Christmas Island")
+ (6722 . "Norfolk Island")
+ (673 . "Brunei")
+ (674 . "Nauru")
+ (675 . "Papua New Guinea")
+ (676 . "Tonga")
+ (677 . "Solomon Islands")
+ (678 . "Vanuatu")
+ (679 . "Fiji")
+ (680 . "Palau")
+ (681 . "Wallis & Futuna Islands")
+ (682 . "Cook Islands")
+ (683 . "Niue")
+ (684 . "American Samoa")
+ (685 . "Western Samoa")
+ (686 . "Kiribati")
+ (687 . "New Caledonia")
+ (688 . "Tuvalu")
+ (689 . "French Polynesia")
+ (690 . "Tokelau")
+ (691 . "Micronesia, Federated States of")
+ (692 . "Marshall Islands")
+ (7 . "Russia")
+ (705 . "Kazakhstan")
+ (706 . "Kyrgyzstan")
+ (708 . "Tajikistan")
+ (709 . "Turkmenistan")
+ (711 . "Uzbekistan")
+ (81 . "Japan")
+ (82 . "Korea, South")
+ (84 . "Viet Nam")
+ (850 . "Korea, North")
+ (852 . "Hong Kong")
+ (853 . "Macau")
+ (855 . "Cambodia")
+ (856 . "Laos")
+ (86 . "China")
+ (880 . "Bangladesh")
+ (886 . "Taiwan")
+ (90 . "Turkey")
+ (91 . "India")
+ (92 . "Pakistan")
+ (93 . "Afghanistan")
+ (94 . "Sri Lanka")
+ (95 . "Myanmar")
+ (960 . "Maldives")
+ (961 . "Lebanon")
+ (962 . "Jordan")
+ (963 . "Syrian Arab Republic")
+ (964 . "Iraq")
+ (965 . "Kuwait")
+ (966 . "Saudi Arabia")
+ (967 . "Yemen")
+ (968 . "Oman")
+ (971 . "United Arabian Emirates")
+ (972 . "Israel")
+ (973 . "Bahrain")
+ (974 . "Qatar")
+ (975 . "Bhutan")
+ (976 . "Mongolia")
+ (977 . "Nepal")
+ (98 . "Iran (Islamic Republic of)")
+ (994 . "Azerbaijan")
+ (995 . "Georgia")
+ (9999 . "other")))
+
+(defmacro emchat-v8-get-country (code)
+ "Return country name according to country CODE."
+ `(emchat-v8-get-alist-value ,code emchat-v8-countries-alist))
+
+(defconst emchat-v8-gender-alist
+ '((0 . "unspecified")
+ (1 . "female")
+ (2 . "male")))
+
+(defmacro emchat-v8-get-gender (code)
+ "Return gender name according to specified gender CODE."
+ `(emchat-v8-get-alist-value ,code emchat-v8-gender-alist))
+
+(defconst emchat-v8-languages-alist
+ '((0 . "not specified")
+ (1 . "Arabic")
+ (2 . "Bhojpuri")
+ (3 . "Bulgarian")
+ (4 . "Burmese")
+ (5 . "Cantonese")
+ (6 . "Catalan")
+ (7 . "Chinese")
+ (8 . "Croatian")
+ (9 . "Czech")
+ (10 . "Danish")
+ (11 . "Dutch")
+ (12 . "English")
+ (13 . "Esperanto")
+ (14 . "Estonian")
+ (15 . "Farsi")
+ (16 . "Finnish")
+ (17 . "French")
+ (18 . "Gaelic")
+ (19 . "German")
+ (20 . "Greek")
+ (21 . "Hebrew")
+ (22 . "Hindi")
+ (23 . "Hungarian")
+ (24 . "Icelandic")
+ (25 . "Indonesian")
+ (26 . "Italian")
+ (27 . "Japanese")
+ (28 . "Khmer")
+ (29 . "Korean")
+ (30 . "Lao")
+ (31 . "Latvian")
+ (32 . "Lithuanian")
+ (33 . "Malay")
+ (34 . "Norwegian")
+ (35 . "Polish")
+ (36 . "Portuguese")
+ (37 . "Romanian")
+ (38 . "Russian")
+ (39 . "Serbian")
+ (40 . "Slovak")
+ (41 . "Slovenian")
+ (42 . "Somali")
+ (43 . "Spanish")
+ (44 . "Swahili")
+ (45 . "Swedish")
+ (46 . "Tagalog")
+ (47 . "Tatar")
+ (48 . "Thau")
+ (49 . "Turkish")
+ (50 . "Ukarinian")
+ (51 . "Urdu")
+ (52 . "Vietnamese")
+ (53 . "Yiddish")
+ (54 . "Yoruba")
+ (55 . "Afriaans")
+ (56 . "Bosnian")
+ (57 . "Persian")
+ (58 . "Albanian")
+ (59 . "Armenian")
+ (60 . "Punjabi")
+ (61 . "Chamorro")
+ (62 . "Mongolian")
+ (63 . "Mandarin")
+ (64 . "Taiwanese")
+ (65 . "Macedonian")
+ (66 . "Sindhi")
+ (67 . "Welsh")
+ (68 . "Azerbaijani")
+ (69 . "Kurdish")
+ (70 . "Gujarati")
+ (71 . "Tamil")
+ (72 . "Belorussian")
+ (255 . "other")))
+
+(defmacro emchat-v8-get-language (code)
+ "Return language name according to language CODE."
+ `(emchat-v8-get-alist-value ,code emchat-v8-languages-alist))
+
+(defconst emchat-v8-marital-alist
+ '((0 . "not specified")
+ (10 . "single")
+ (11 . "in a long-term relationship")
+ (12 . "engaged")
+ (20 . "married")
+ (30 . "divorced")
+ (31 . "separated")
+ (40 . "widowed")))
+
+(defmacro emchat-v8-get-marital (code)
+ "Return marital name according to marital CODE."
+ `(emchat-v8-get-alist-value ,code emchat-v8-marital-alist))
+
+;;;; SRV
+
+;;; Family #x13 (SSI - Server Side Info)
+
+;;; FIXME: This should most likely be used to set some max values in
+;;; EMchat, but I'm not that concerned seeing as though max contacts
+;;; is 3000.
+(defun emchat-v8-snac-srv-ssi-rights-reply (ectx data &optional flags)
+ "SRV_SSI_RIGHTS_REPLY, SNAC(#x13, #x03)."
+ (let* ((tlvs (emchat-v8-fetch-tlvs data))
+ (limits (emchat-v8-tlv-val (emchat-v8-tlv-get tlvs 4)))
+ (mconts (emchat-v8-fetch-word limits)) ; max contacts
+ (mgrps (emchat-v8-fetch-word limits)) ; max groups
+ (mvconts (emchat-v8-fetch-word limits)) ; max visible contacts
+ (miconts (emchat-v8-fetch-word limits)) ; max invisible contacts
+ (mvibit (emchat-v8-fetch-word limits)) ; max vis/invis bitmasks
+ (mpres (emchat-v8-fetch-word limits)) ; max presence info fields
+ (mignores ; max ignore entries
+ (progn
+ (dotimes (i 8)
+ (emchat-v8-fetch-word limits))
+ (emchat-v8-fetch-word limits)))
+ ;; rest of the thing is ignored for now (unknown stuff)
+ )
+ ;; not sure what to do with this yet, lets just log it for now
+ (emchat-v8-debug "SRV_SSI_RIGHTS_REPLY: Max number of...
+Contacts=%d
+Groups=%d
+Visible Contacts=%d
+Invisible Contacts=%d
+Vis/Invis Bitmasks=%d
+Presense Info Fields=%d
+Ignore List Entries=%d"
+ mconts mgrps mvconts miconts mvibit mpres mignores)))
+
+(defvar emchat-v8-ssi-count nil
+ "A place to store SSI entry count when it spans multiple packets.")
+
+;;; FIXME: handle BARTs
+(defun emchat-v8-snac-srv-ssi-reply (ectx data &optional flags)
+ "SRV_SSI_REPLY, SNAC(#x13, #x06)."
+ (let* ((count (progn
+ (emchat-v8-fetch-byte data) ; skip, just a version number
+ (emchat-v8-fetch-word data)))
+ lastupd)
+ (push count emchat-v8-ssi-count)
+ (dotimes (i count)
+ (let* ((name (emchat-v8-fetch-bstr data))
+ (group (emchat-v8-fetch-word data))
+ (id (emchat-v8-fetch-word data))
+ (type (emchat-v8-fetch-word data))
+ (tlvs-len (emchat-v8-fetch-word data))
+ (tlvs (emchat-v8-fetch-n-tlvs data tlvs-len))
+ ttype tlen tval)
+ (while tlvs
+ (setq ttype (emchat-v8-tlv-type (car tlvs)))
+ (setq tlen (emchat-v8-tlv-len (car tlvs)))
+ (setq tval (emchat-v8-tlv-val (car tlvs)))
+ (when (and (eq ttype #x131) (not (eq type #x14)))
+ (emchat-world-sync-ssi-maybe name group id tval))
+ (emchat-v8-debug "SSI_REPLY_TLV:
+name=%S group=%S id=%S type=%S
+ttype=%S tlength=%S tvalue=%S"
+ name group id type ttype tlen tval)
+ (setq tlvs (cdr tlvs)))))
+ (with-current-buffer (find-file-noselect emchat-world-rc-filename)
+ (when (buffer-modified-p)
+ (save-buffer)))
+ (when (zerop (logand flags 1))
+ (when (> (length emchat-v8-ssi-count) 1)
+ (setq count (apply #'+ emchat-v8-ssi-count)))
+ (setq emchat-v8-ssi-count nil)
+ (setq lastupd (emchat-v8-fetch-time data))
+ (emchat-world-update-world-count count lastupd)
+ (emchat-v8-debug "SSI_REPLY: count=%S lastupd=%S" count lastupd))))
+
+(defun emchat-v8-snac-srv-ssi-mod-ack (ectx data &optional flags)
+ "Server ack for buddy add/del/mod. SNAC(#x13, #x0E)."
+ (let ((retcodes '((#x0000 . "Success")
+ (#x0002 . "Item not found")
+ (#x0003 . "Item already exists")
+ (#x000A . "Invalid data")
+ (#x000C . "Limit exceeded")
+ (#x000D . "Can't add ICQ contact to AIM list")
+ (#x000E . "Authorisation required"))))
+ (setq emchat-add-user-success nil)
+ (while data
+ (let* ((code (emchat-v8-fetch-word data))
+ (retstr (cdr (assq code retcodes))))
+ (emchat-v8-debug "SRV_SSI_MOD_ACK: %s" retstr)
+ (if (zerop code)
+ (emchat-v8-ctx-run-incoming-handler 'ectx 'new-user)
+ (emchat-log-error "SSI Modifications Error: %s" retstr))))))
+
+(defun emchat-v8-snac-srv-ssi-up-to-date (ectx data &optional flags)
+ "Local copy of SSI is up to date. SNAC(#x13, #x0F).
+
+This doesn't actually do anything because there isn't any point. It
+sends back the mod time and item count, but you only get this packet
+if your local SSI has the same mod time and item count."
+ (emchat-log-info "Local copy of SSI is up to date!")
+ (emchat-v8-debug "SRV_SSI_UP_TO_DATE: local SSI is up to date."))
+
+
+(defun emchat-v8-snac-srv-ssi-auth-reply (ectx data &optional flags)
+ "SRV_SSI_AUTH_REPLY, SNAC (#x13 . #x1B)"
+ (let ((buin (emchat-v8-fetch-buin data))
+ (accept (emchat-v8-fetch-byte data))
+ (reason (emchat-v8-fetch-bstr data)))
+ (emchat-v8-debug "AUTHREPLY: from %d %s"
+ buin
+ (if (zerop accept)
+ "rejected"
+ "accepted"))
+ (if (zerop accept)
+ (emchat-v8-ctx-run-incoming-handler ectx 'auth-reject
+ :uin buin :msg reason :msg-type 'auth-reject)
+ (emchat-v8-ctx-run-incoming-handler ectx 'auth-accept
+ :uin buin :msg reason :msg-type 'auth-accept))))
+
+(defun emchat-v8-snac-srv-ssi-you-were-added (ectx data &optional flags)
+ "SRV_ADDEDYOU, SNAC (#x13 . #x1C)"
+ (let ((buin (emchat-v8-fetch-buin data))
+ (msg "has added you to their contact list."))
+ (emchat-v8-debug "ADDEDYOU: by %d" buin)
+ (emchat-v8-ctx-run-incoming-handler ectx 'added-you
+ :uin buin :msg msg :msg-type 'added)))
+
+(defun emchat-v8-snac-srv-ssi-future-auth-granted (ectx data &optional flags)
+ "Future auth has been given. SNAC(#x13, #x15)."
+ (let ((uin (emchat-v8-fetch-buin data))
+ (reason (emchat-v8-fetch-bstr data)))
+ (emchat-v8-debug "SRV_SSI_FUTURE_AUTH_GRANTED: %s grants auth because: %s"
+ uin reason)
+ (emchat-v8-ctx-run-incoming-handler ectx 'auth-accept
+ :uin uin :msg reason :msg-type 'auth-accept)))
+
+(defun emchat-v8-snac-srv-ssi-auth-request (ectx data &optional flags)
+ "SRV_SSI_AUTH_REQUEST, SNAC (#x13 . #x19)"
+ (let ((buin (emchat-v8-fetch-buin data))
+ (reason (emchat-v8-fetch-bstr data)))
+ (emchat-v8-debug "AUTHREQ: from %d Reason: %S" buin reason)
+ (emchat-v8-ctx-run-incoming-handler ectx 'auth-request
+ :uin buin :msg reason :msg-type 'auth-request)))
+
+;;; Family #x15 (Old ICQ)
+
+;;; FIXME: complete this, a fair bit is still missing. Might need
+;;; splitting up into several functions
+(defun emchat-v8-snac-srv-fromicqsrv (ectx data &optional flags)
+ "SRV_FROMICQSRV, SNAC(#x15, #x03)"
+ (let* ((tlv1 (emchat-v8-tlv-val (emchat-v8-fetch-single-tlv data)))
+ (len (emchat-v8-fetch-word-le tlv1))
+ (my-uin (emchat-v8-fetch-uin tlv1))
+ (type (emchat-v8-fetch-word-le tlv1))
+ (seq (emchat-v8-fetch-word-le tlv1))
+ (his-uin (cdr (assq seq (emchat-v8-ctx-get-prop ectx 'about-query-seq-uin)))))
+ ;; Shutup compiler
+ (setq len len my-uin my-uin)
+
+ (emchat-v8-debug "FROMICQSRV: UIN: %S, Type=%d, seq=%d, tlv1=%S, data=%S"
+ his-uin type seq tlv1 data)
+
+ (cond ((= type 65)
+ (emchat-v8-recv-message ectx 'offline-message tlv1))
+
+ ((= type 66)
+ ;; Ack end of offline messages
+ (emchat-v8-send ectx
+ (emchat-v8-pack-meta-snac ectx 62))
+ (emchat-v8-ctx-run-incoming-handler ectx 'end-offline-messages))
+
+ ((= type 2010)
+ (let ((subtype (emchat-v8-fetch-word-le tlv1))
+ (result (emchat-v8-fetch-byte tlv1)))
+ (emchat-v8-debug "SRV_META: Subtype=%d, result=%d, tlv1=%S" subtype result tlv1)
+
+ (when (= result 10)
+ (cond ((= subtype 200)
+ ;; -- Start --
+ ;; GENERAL
+ (let ((nick (emchat-v8-fetch-lnts tlv1))
+ (fname (emchat-v8-fetch-lnts tlv1))
+ (sname (emchat-v8-fetch-lnts tlv1))
+ (email (emchat-v8-fetch-lnts tlv1))
+ (city (emchat-v8-fetch-lnts tlv1))
+ (state (emchat-v8-fetch-lnts tlv1))
+ (phone (emchat-v8-fetch-lnts tlv1))
+ (fax (emchat-v8-fetch-lnts tlv1))
+ (street (emchat-v8-fetch-lnts tlv1))
+ (cellular (emchat-v8-fetch-lnts tlv1))
+ (zip (emchat-v8-fetch-lnts tlv1))
+ (country (emchat-v8-get-country
+ (emchat-v8-fetch-word-le tlv1)))
+ ;; The timezone the user lives in, as
+ ;; multiples of 30minutes relative to UTC.
+ (tz (emchat-v8-fetch-byte tlv1))
+ (flags (emchat-v8-fetch-byte tlv1))
+ (web-ind (= (emchat-v8-fetch-word-le tlv1) 1)))
+
+ (emchat-v8-debug "GENERAL-Info: UIN: %d, Nick: %s"
+ his-uin nick)
+
+ (emchat-v8-ctx-run-incoming-handler ectx 'about-general
+ :uin his-uin
+ :nick nick :first-name fname :second-name sname
+ :email email :city city :state state :phone phone
+ :fax fax :street street :cellular cellular
+ :zip-code zip :country country :tz tz
+ :flags flags :web-indicator web-ind)))
+
+ ((= subtype 210)
+ ;; WORK
+ ;; Hey! Does anybody actually care about this? --lg
+ )
+ ((= subtype 220)
+ ;; MORE
+ (let ((age (emchat-v8-fetch-word-le tlv1))
+ (gender (emchat-v8-get-gender
+ (emchat-v8-fetch-byte tlv1)))
+ (homepage (emchat-v8-fetch-lnts tlv1))
+ (birth-year (emchat-v8-fetch-word-le tlv1))
+ (birth-month (emchat-v8-fetch-byte tlv1))
+ (birth-day (emchat-v8-fetch-byte tlv1))
+ (lang1 (emchat-v8-get-language
+ (emchat-v8-fetch-byte tlv1)))
+ (lang2 (emchat-v8-get-language
+ (emchat-v8-fetch-byte tlv1)))
+ (lang3 (emchat-v8-get-language
+ (emchat-v8-fetch-byte tlv1)))
+ (ocity (progn
+ (emchat-v8-fetch-word-le tlv1) ; skip
+ (emchat-v8-fetch-lnts tlv1)))
+ (ostate (emchat-v8-fetch-lnts tlv1))
+ (ocountry (emchat-v8-get-country
+ (emchat-v8-fetch-word-le tlv1)))
+ (marital (emchat-v8-get-marital
+ (emchat-v8-fetch-word-le tlv1))))
+ (emchat-v8-ctx-run-incoming-handler ectx 'about-more
+ :uin his-uin :age age :gender gender :homepage homepage
+ :birth-year birth-year :birth-month birth-month
+ :birth-day birth-day :lang1 lang1 :lang2 lang2
+ :lang3 lang3 :ocity ocity :ostate ostate
+ :ocountry ocountry :marital marital)))
+
+ ((= subtype 235)
+ ;; EMAILS
+ )
+ ((= subtype 270)
+ ;; META270
+ )
+ ((= subtype 230)
+ ;; ABOUT
+ (let ((about-user (emchat-v8-fetch-lnts tlv1)))
+ (emchat-v8-debug "USER ABOUT-Info: %S" about-user)
+ (emchat-v8-ctx-run-incoming-handler ectx 'about-about
+ :uin his-uin :about about-user)))
+
+ ((= subtype 240)
+ ;; INTEREST
+ )
+ ((= subtype 250)
+ ;; BACKGROUND
+ )
+
+ ((= subtype 420)
+ ;; Search found a user
+ (let ((uin (progn (emchat-v8-fetch-word-le tlv1)
+ (emchat-v8-fetch-uin tlv1)))
+ (nick (emchat-v8-fetch-lnts tlv1))
+ (first-name (emchat-v8-fetch-lnts tlv1))
+ (last-name (emchat-v8-fetch-lnts tlv1))
+ (email (emchat-v8-fetch-lnts tlv1))
+ (auth (emchat-v8-fetch-byte tlv1))
+ (status (emchat-v8-fetch-word-le tlv1))
+ (gender (emchat-v8-get-gender
+ (emchat-v8-fetch-byte tlv1)))
+ (age (emchat-v8-fetch-word-le tlv1))
+ (missed (emchat-v8-fetch-word-le tlv1)))
+ (emchat-v8-debug "FOUND USER: UIN=%d, Nick=%s, missed=%d" uin nick missed)
+ (emchat-v8-ctx-run-incoming-handler ectx 'search-found
+ :uin uin :nick nick
+ :first-name first-name :last-name last-name
+ :email email :auth auth :status status :gender gender
+ :age age :missed missed)))
+
+ ((= subtype 430)
+ ;; Search found a user (the last match from the search)
+ (let ((uin (progn (emchat-v8-fetch-word-le tlv1)
+ (emchat-v8-fetch-uin tlv1)))
+ (nick (emchat-v8-fetch-lnts tlv1))
+ (first-name (emchat-v8-fetch-lnts tlv1))
+ (last-name (emchat-v8-fetch-lnts tlv1))
+ (email (emchat-v8-fetch-lnts tlv1))
+ (auth (emchat-v8-fetch-byte tlv1))
+ (status (emchat-v8-fetch-word-le tlv1))
+ (gender (emchat-v8-get-gender
+ (emchat-v8-fetch-byte tlv1)))
+ (age (emchat-v8-fetch-word-le tlv1))
+ (missed (emchat-v8-fetch-word-le tlv1)))
+ (emchat-v8-debug "FOUND USER: UIN=%d, Nick=%s, missed=%d" uin nick missed)
+ (emchat-v8-ctx-run-incoming-handler ectx 'search-found-last
+ :uin uin :nick nick
+ :first-name first-name :last-name last-name
+ :email email :auth auth :status status :gender gender
+ :age age :missed missed)))
+ )))))
+ ))
+
+(defun emchat-v8-snac-srv-toicqerr (ectx data &optional flags)
+ "SRV_TOICQERR, SNAC(0x15, 0x01)"
+ (let ((ecode (emchat-v8-fetch-word data))
+ (tlv1 (emchat-v8-fetch-single-tlv data)))
+ (error "Malformed TOICQ request" ecode tlv1)))
+
+(defun emchat-v8-snac-srv-set-interval (ectx data &optional flags)
+ "SRV_SETINTERVAL, SNAC(0x0B, 0x02)"
+ (let ((ival (emchat-v8-fetch-word data)))
+ (emchat-v8-debug "User info interval: %S" ival)
+ (emchat-v8-ctx-put-prop ectx 'user-info-interval ival)))
+
+(defun emchat-v8-snac-srv-icbm-err (ectx data &optional flags)
+ "SRV_ICBMERR"
+ (let* ((ival (emchat-v8-fetch-word data))
+ (err (cond ((= ival 4) "User offline")
+ ((= ival 9) "Client does not understand type-2 mesasges")
+ ((= ival 14) "Packet was malformed")
+ (t "Unknown"))))
+ (emchat-v8-debug "ICBMERR: %d/%s" ival err)))
+
+(defun emchat-v8-snac-srv-reply-icbm (ectx data &optional flags)
+ "SRV_REPLICBM, SNAC(#x04, #x05)"
+ )
+
+(defun emchat-v8-snac-srv-replyinfo (ectx data &optional flags)
+ "SRV_REPLYINFO, SNAC(1, f)"
+ ;; BUIN xx .. UIN The UIN this information is about.
+ ;; WORD.B 00 00 WARNING Probably a warning level left over from OSCAR.
+ ;; WORD.B 00 xx COUNT Total number of TLVs to follow.
+ ;; TLV(1) 00 01 00 02 00 80 UNKNOWN Unknown.
+ ;; TLV(12) 00 0c 00 25 ... CLI2CLI Direct connection info, see CLI_SETSTATUS SNAC(1,30).
+ ;; TLV(15) 00 0f 00 04 xx xx xx xx UNKNOWN Number of seconds that user has been online?
+ ;; TLV(2) 00 02 00 04 TIME MEMBERTIME The member since time.
+ ;; TLV(3) 00 03 00 04 TIME ONLINETIME The online since time.
+ ;; TLV(5) 00 05 00 04 TIME UNKNOWN Some unknown time.
+ ;; TLV(6) 00 06 00 04 xx xx xx xx STATUS The current online status.
+ ;; TLV(30) 00 1e 00 04 00 00 00 00 UNKNOWN Unknown: empty.
+; (let* ((uin (emchat-v8-fetch-buin data))
+; (tlvs (progn
+; (emchat-v8-fetch-word data) ; skip (warning)
+; (emchat-v8-fetch-word data) ; skip (tlv count)
+; (emchat-v8-fetch-tlvs data)))
+; (tlv12 (emchat-v8-tlv-get tlvs 12))) ; CLI2CLI
+
+; (emchat-v8-debug "SRV_REPLYINFO: UIN=%d tlv12=%S" uin tlv12)
+; ))
+ )
+
+(defun emchat-v8-snac-srv-reply-buddy (ectx data &optional flags)
+ "SRV_REPLYBUDDY, SNAC(0x03, 0x03)"
+ (let* ((tlvs (emchat-v8-fetch-tlvs data))
+ (muaicl (emchat-v8-tlv-get tlvs 1)) ;maximum uins allowed in contact list
+ (mpchuu (emchat-v8-tlv-get tlvs 2))) ;maximum number of people that can have our uin in contact list
+ (when muaicl
+ (emchat-v8-ctx-put-prop ectx 'maximum-uins (emchat-v8-tlv-num muaicl)))
+ (when mpchuu
+ (emchat-v8-ctx-put-prop ectx 'maximum-people (emchat-v8-tlv-num mpchuu)))))
+
+(defun emchat-v8-snac-srv-user-online (ectx data &optional flags)
+ "SRV_USERONLINE, SNAC(0x03, 0x0B)."
+ (let* ((buin (emchat-v8-fetch-buin data))
+ (tlvs (progn
+ (emchat-v8-fetch-data data 4) ; skip
+ (emchat-v8-fetch-tlvs data)))
+ (ts (emchat-v8-tlv-get tlvs 6))
+ ;; XXX use only last 2 bytes of status
+ (new-status (and ts (emchat-v8-find-status
+ (progn
+ (emchat-v8-fetch-word (emchat-v8-tlv-val ts))
+ (emchat-v8-fetch-word (emchat-v8-tlv-val ts)))))))
+ (emchat-v8-debug "SRV_USERONLINE: uin=%d status=%S/%S"
+ buin ts new-status)
+ (when new-status
+ (emchat-v8-ctx-run-incoming-handler ectx 'status-update
+ buin new-status))))
+
+(defun emchat-v8-snac-srv-user-offline (ectx data &optional flags)
+ "SRV_USEROFFLINE, SNAC(0x03, 0x0C)"
+ (let ((buin (emchat-v8-fetch-buin data)))
+ (emchat-v8-debug "SRV_USEROFFLINE: uin=%d" buin)
+ (emchat-v8-ctx-run-incoming-handler ectx 'status-update
+ buin 'offline)))
+
+(defun emchat-v8-snac-srv-reply-location (ectx data &optional flags)
+ "SRV_REPLYLOCATION, SNAC(0x02, 0x03)."
+ ;; TODO: -write me
+ (let* ((tlvs (emchat-v8-fetch-tlvs data))
+ (mcap (emchat-v8-tlv-get tlvs 2)))
+ (when mcap
+ ;; Set maximum capabilities
+ (emchat-v8-debug "max capabilities: %S" (emchat-v8-tlv-num mcap))
+ (emchat-v8-ctx-put-prop ectx 'maximum-capabilities (emchat-v8-tlv-num mcap)))))
+
+(defun emchat-v8-snac-srv-families (ectx data &optional flags)
+ "SRV_FAMILIES, SNAC(0x01, 0x03)."
+ (let (srv-families)
+ (while (> (length (aref data 0)) 0)
+ (setq srv-families
+ (cons (emchat-v8-fetch-word data) srv-families)))
+ (emchat-v8-ctx-put-prop ectx 'server-families srv-families))
+
+ (emchat-v8-debug "SRV-FAMILIES %S" (emchat-v8-ctx-get-prop ectx 'server-families))
+ (emchat-v8-snac-cli-families ectx))
+
+(defun emchat-v8-snac-srv-families2 (ectx data &optional flags)
+ "SRV_FAMILIES2, SNAC(0x01, 0x12)."
+ (emchat-v8-debug "SRV-FAMILIES2 %S" data)
+ )
+
+(defun emchat-v8-snac-bart-request (ectx data &optional flags)
+ "BART_REQUEST, SNAC(0x01, 0x21)."
+ (let* ((type (emchat-v8-fetch-word data))
+ (flag (emchat-v8-fetch-byte data))
+ (len_opaque (emchat-v8-fetch-byte data))
+ (opaque (emchat-v8-fetch-data data len_opaque)))
+ (emchat-v8-debug "[BART]...
+Type: %S
+Flag: %S
+len: %S
+opaque: %S"
+ type flag len_opaque opaque)))
+
+(defun emchat-v8-snac-srv-rates (ectx data &optional flags)
+ "SRV_RATES, SNAC(0x01, 0x07)."
+ (let ((nr (emchat-v8-parse-message
+ data
+ (list
+ [2 emchat-v8-length-1]
+ [emchat-v8-length-1
+ ([2 number] ; Rate class ID
+ [4 number] ; Window size
+ [4 number] ; Clear level
+ [4 number] ; Alert level
+ [4 number] ; Limit level
+ [4 number] ; Disconnect level
+ [4 number] ; Current level
+ [4 number] ; Max level
+ [4 number] ; last time
+ [1 number])] ; current state
+ [emchat-v8-length-1
+ ([2 number] ; Rate class ID
+ [2 emchat-v8-length-2] ; number of pairs in group
+ [emchat-v8-length-2 ([4 number])])]))))
+
+ (emchat-v8-debug "SRV_RATES: %S" nr)
+
+ ;; Send a reply
+ (when (cadr nr)
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x01 . #x08)
+ (apply 'concat
+ (mapcar 'emchat-v8-pack-word (mapcar 'car (nth 1 nr)))))))
+ ))
+
+(defun emchat-v8-snac-srv-rate-change (ectx data &optional flags)
+ "SRV_RATE_CHANGE, SNAC(#x01, #x0A)."
+ (let ((code (emchat-v8-fetch-word data))
+ (rateid (emchat-v8-fetch-word data))
+ (winsize (emchat-v8-fetch-dword data))
+ (clear (emchat-v8-fetch-dword data))
+ (alert (emchat-v8-fetch-dword data))
+ (limit (emchat-v8-fetch-dword data))
+ (discon (emchat-v8-fetch-dword data))
+ (currl (emchat-v8-fetch-dword data))
+ (max (emchat-v8-fetch-dword data))
+ (ltime (emchat-v8-fetch-dword data))
+ (currs (emchat-v8-fetch-byte data)))
+ (emchat-v8-debug
+ "[SRV_RATE_EXCEEDED]:
+ Message Code: %d
+ Rate Class ID: %d
+ Window Size: %d
+ Clear Level: %d
+ Alert Level: %d
+ Limit Level: %d
+Disconnect Level: %d
+ Current Level: %d
+ Max Level: %d
+ Last Time: %d
+ Current State: %d"
+ code rateid winsize clear alert limit discon currl max ltime currs)
+ (ecase code
+ (1 #'ignore)
+ (2 (emchat-log-info "You've reached the rate limit: %d
+Chill out, take a break, have a coffee." alert))
+ (3 (emchat-log-error "Rate limit passed: %d
+Hope you get to read this before you get disconnected" discon))
+ (4 #'ignore))))
+
+(defun emchat-v8-snac-srv-pause (ectx data &optional flags)
+ "SRV_SERVERPAUSE, SNAC(1, B)."
+ ;; Send CLI_ACKSERVERPAUSE snac
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x09 . #x02)
+ (apply 'concat (mapcar #'(lambda (fam)
+ (emchat-v8-pack-word (car fam)))
+ emchat-v8-snacv-list))))
+
+ ;; Mark ECTX as in pause, until SRV_MIGRATIONREQ is received
+ (setf (emchat-v8-ctx-pause-p ectx) t))
+
+(defun emchat-v8-snac-srv-migrate (ectx data &optional flags)
+ "SRV_MIGRATIONREQ, SNAC(1, 12)."
+ (let* ((tlvs (progn
+ (emchat-v8-fetch-word data)
+ (emchat-v8-fetch-tlvs data)))
+ (tlv5 (emchat-v8-tlv-get tlvs 5))
+ (tlv6 (emchat-v8-tlv-get tlvs 6)))
+
+ ;; Close current connection
+ (emchat-v8-close ectx)
+
+ (let* ((nsrv (split-string (emchat-v8-tlv-str tlv5) ":"))
+ (addr (nth 0 nsrv))
+ (port (string-to-int (nth 1 nsrv))))
+ (emchat-v8-debug "Migrating to new server: %s:%d" addr port)
+ ;; Store cookie and reconnect
+ (emchat-v8-ctx-put-prop ectx 'cli-cookie (emchat-v8-tlv-str tlv6))
+ (emchat-v8-connect ectx addr port))))
+
+(defun emchat-v8-snac-srv-motd (ectx data &optional flags)
+ "SRV_MOTD, SNAC(1, 13)."
+ (emchat-v8-debug "SRV_MOTD")
+
+ (emchat-v8-snac-cli-ratesrequest ectx)
+ (emchat-v8-snac-cli-reqinfo ectx)
+
+ ;; TODO: roster
+ (emchat-v8-snac-cli-reqlocation ectx)
+ (emchat-v8-snac-cli-reqbuddy ectx)
+ (emchat-v8-snac-cli-reqicbm ectx)
+ (emchat-v8-snac-cli-reqbos ectx)
+
+ (emchat-v8-ctx-run-incoming-handler ectx 'connected))
+
+(defconst emchat-v8-msg-types
+ '((0 . automatic) ; An automatic message
+ (1 . normal) ; A plain normal message
+ (2 . chat-request) ; A chat request
+ (3 . file-transfer-request) ; A file transfer request
+ (4 . url) ; An URL message. The message consists of the description and the url
+ (6 . auth-request) ; An authorization request
+ (7 . auth-reject) ; An authorization reject message
+ (8 . auth-accept) ; An authorization accept message
+ (12 . added) ; You were added to the sender's contact list
+ (13 . web-pager) ; A message sent through www.icq.com's web pager
+ (14 . email-pager) ; A message sent through the email pager ([uin]@pager.icq.com)
+ (19 . contact-list) ; A contact list message
+ (26 . extended) ; An extended message. The packet will contain more data
+ (1000 . get-away) ; A message requesting the "away" auto message
+ (1001 . get-occ) ; A message requesting the "occupied" auto message
+ (1002 . get-na) ; A message requesting the "not available" auto message
+ (1003 . get-dnd) ; A message requesting the "do not disturb" auto message
+ (1004 . get-ffc) ; A message requesting the "free for chat" auto message
+ )
+ "List of message types.")
+
+(defconst emchat-v8-msg-mass-flag #x8000
+ "If set, message was sent to several recipients.")
+
+(defun emchat-v8-snac-srv-recv-msg (ectx data &optional flags)
+ "SRV_RECVMSG, SNAC(4, 7)."
+ (emchat-v8-debug "data here: %S" data)
+ (let ((midtime (emchat-v8-fetch-time data))
+ (midrand (emchat-v8-fetch-dword data))
+ (type (emchat-v8-fetch-word data))
+ (uin (emchat-v8-fetch-buin data))
+ (warn (emchat-v8-fetch-word data))
+ (count (emchat-v8-fetch-word data))
+ (tlvs (emchat-v8-fetch-tlvs data)))
+
+ ;; Fetch tlvs
+ (emchat-v8-debug "Got message from %S, mt/mr/t/w/c=%S/%S/%S/%S/%S, tlvs=%S"
+ uin midtime midrand type warn count tlvs)
+
+ (cond ((= type 1)
+ ;; Normal message
+ (let* ((tlvals (emchat-v8-fetch-tlvs
+ (emchat-v8-tlv-val (emchat-v8-tlv-get tlvs 2))))
+ (caps (emchat-v8-fetch-byte
+ (emchat-v8-tlv-val (emchat-v8-tlv-get tlvals 1281))))
+ (mtlval (emchat-v8-tlv-val
+ (emchat-v8-tlv-get tlvals 257)))
+ (menc (emchat-v8-fetch-word mtlval))
+ (msg (progn
+ (emchat-v8-fetch-word mtlval) ; skip
+ (emchat-v8-fetch-string mtlval))))
+
+ (emchat-v8-debug "Normal message: caps/menc=%d/%d, msg='%s'"
+ caps menc msg)
+ (emchat-v8-ctx-run-incoming-handler ectx 'instant-message
+ :uin uin :msg msg :msg-type 'normal)))
+
+ ((= type 2)
+ ;; Advanced message
+ ;; TODO: -write me
+ (emchat-v8-debug "MSG[%d]: here" type))
+
+ ((= type 4)
+ ;; Server message
+ (let* ((tlv5 (emchat-v8-tlv-val (emchat-v8-tlv-get (nreverse tlvs) 5)))
+ (uin (truncate (emchat-v8-fetch-uin tlv5)))
+ (mtype (emchat-v8-fetch-word-le tlv5))
+ (msg (emchat-v8-fetch-lnts tlv5))
+ msg-type)
+ ;; Adjust MTYPE to remove flag fields (MSGF_MASS)
+ (setq mtype (logand mtype (lognot emchat-v8-msg-mass-flag)))
+ (setq msg-type (cdr (assoc mtype emchat-v8-msg-types)))
+
+ (emchat-v8-ctx-run-incoming-handler ectx 'instant-message
+ :uin uin :msg msg :msg-type msg-type)))
+
+ (t (error "Unknown message type")))))
+
+(defun emchat-v8-snac-srv-missed-icbm (ectx data &optional flags)
+ "SRV_MISSED_ICBM, SNAC(4, 10)."
+ (let* ((buin (progn
+ (emchat-v8-fetch-word data) ; skip channel
+ (emchat-v8-fetch-buin data)))
+ (mmsgs (progn
+ (emchat-v8-fetch-word data) ; skip warn
+ (dotimes (n (emchat-v8-fetch-word data)) ; skip tlvs
+ (emchat-v8-fetch-single-tlv data))
+ (emchat-v8-fetch-word data)))
+ (rn (emchat-v8-fetch-word data))
+ (reasons '((0 . "Invalid message")
+ (1 . "Message too large")
+ (2 . "Message rate limit exceeded")
+ (3 . "Sender too evil (sender warn level > your max_msg_sevil)")
+ (4 . "You are too evil (sender max_msg_revil > your warn level)")))
+ (reason (or (cdr (assq rn reasons)) "Unknown reason")))
+ (emchat-v8-ctx-run-incoming-handler ectx 'missed-message
+ :uin buin :missed-messages mmsgs :reason reason)))
+
+(defun emchat-v8-snac-srv-contact-err (ectx data &optional flags)
+ "SRV_CONTACTERR, SNAC(3, #x01)."
+ (let* ((ercode (emchat-v8-fetch-word data))
+ (errmsg (cond ((= ercode #x0E) "Empty UIN list sent")
+ ((= ercode #x14) "Non existant UIN")
+ ((= ercode #x15) "Contact list full"))))
+ (emchat-v8-debug "[SRV_CONTACTERR]: Code=%d (0x%1$02X), Msg=%s" ercode errmsg)
+ (emchat-v8-ctx-run-incoming-handler ectx 'srv-contacterr :reason errmsg)))
+
+(defun emchat-v8-snac-srv-err (ectx data &optional flags)
+ "SRV_GEN_ERR, SNAC(1, #x01)."
+ (let* ((ercode (emchat-v8-fetch-word data))
+ (errmsg (cond ((= ercode #x01) "Invalid SNAC header.")
+ ((= ercode #x02) "Server rate limit exceeded")
+ ((= ercode #x03) "Client rate limit exceeded")
+ ((= ercode #x04) "Recipient is not logged in")
+ ((= ercode #x05) "Requested service unavailable")
+ ((= ercode #x06) "Requested service not defined")
+ ((= ercode #x07) "You sent obsolete SNAC")
+ ((= ercode #x08) "Not supported by server")
+ ((= ercode #x09) "Not supported by client")
+ ((= ercode #x0A) "Refused by client")
+ ((= ercode #x0B) "Reply too big")
+ ((= ercode #x0C) "Responses lost")
+ ((= ercode #x0D) "Request denied")
+ ((= ercode #x0E) "Incorrect SNAC format")
+ ((= ercode #x0F) "Insufficient rights")
+ ((= ercode #x10) "In local permit/deny (recipient blocked)")
+ ((= ercode #x11) "Sender too evil")
+ ((= ercode #x12) "Receiver too evil")
+ ((= ercode #x13) "User temporarily unavailable")
+ ((= ercode #x14) "No match")
+ ((= ercode #x15) "List overflow")
+ ((= ercode #x16) "Request ambiguous")
+ ((= ercode #x17) "Server queue full")
+ ((= ercode #x18) "Not while on AOL")
+ (t "Unknown error"))))
+ (emchat-v8-debug "SRV_GEN_ERR: %s" errmsg)
+ (emchat-v8-ctx-run-incoming-handler ectx 'srv-error :reason errmsg)))
+
+(defun emchat-v8-snac-srv-reply-bos (ectx data &optional flags)
+ "SRV_REPLYBOS, SNAC(9, 3)."
+ (emchat-v8-snac-cli-setuserinfo ectx)
+ (emchat-v8-snac-cli-setstatus
+ ectx (emchat-v8-ctx-get-prop ectx 'initial-status))
+ (emchat-v8-snac-cli-ready ectx)
+ ;; This is the now unsupported local-only type of contact list.
+ ;; (emchat-v8-snac-cli-add-contact ectx)
+ (emchat-v8-snac-cli-reqofflinemsgs ectx))
+
+(defun emchat-v8-snac-srv-srv-ack-msg (ectx data &optional flags)
+ "SRV_SRVACKMSG, SNAC (4 . #x0C)"
+ (let ((type (progn
+ (emchat-v8-fetch-data data 8) ; skip
+ (emchat-v8-fetch-word data)))
+ (buin (emchat-v8-fetch-buin data)))
+ (emchat-v8-debug "SRVACKMSG: type=%d uin=%d" type buin)
+ ))
+
+;;;; CLI
+
+;;; Family #x13 (SSI -- Server Side Info)
+
+(defun emchat-v8-snac-cli-ssi-right-request (ectx)
+ "Request rights/limitations for SSI. SNAC(#x13, #x02)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x13 . #x02))))
+
+(defun emchat-v8-snac-cli-ssi-request (ectx)
+ "Request server side info. SNAC(#x13, #x04)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x13 . #x04))))
+
+(defun emchat-v8-snac-cli-ssi-checkout (ectx)
+ "Checkout SSI list if local copy is out of date. SNAC(#x13, #x05)."
+ (let ((num (emchat-world-ssi-count))
+ (modt (emchat-world-ssi-mod-time)))
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x13 . #x05)
+ (emchat-v8-pack-time modt)
+ (emchat-v8-pack-word num)))))
+
+(defun emchat-v8-snac-cli-ssi-activate (ectx)
+ "Activate SSI. SNAC(#x13, #x07)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x13 . #x07))))
+
+;;; FIXME: This isn't working.
+(defun emchat-v8-snac-cli-ssi-add (ectx uin grp id nick)
+ "Add contacts to SSI. SNAC(#x13, #x08)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x13 . #x08)
+ (emchat-v8-pack-bstr uin)
+ (emchat-v8-pack-word grp)
+ (emchat-v8-pack-word id)
+ (emchat-v8-pack-word #x0000)
+ (emchat-v8-pack-tlv #x0131 nick))))
+
+;;; FIXME: Write me
+(defalias 'emchat-v8-snac-cli-ssi-update #'ignore)
+;; (defun emchat-v8-snac-cli-ssi-update (ectx &rest entries)
+;; "Update existing SSI entries. SNAC(#x13, #x09)."
+;; (emchat-v8-debug "CLI_SSI_UPDATE: somebody impliment me"))
+
+;;; FIXME: Write me
+(defalias 'emchat-v8-snac-cli-ssi-delete #'ignore)
+;; (defun emchat-v8-snac-cli-ssi-delete (ectx &rest entries)
+;; "Delete existing SSI entries. SNAC(#x13, #x0A)."
+;; (emchat-v8-debug "CLI_SSI_DELETE: somebody impliment me"))
+(defalias 'emchat-v8-snac-cli-ssi-edit-begin #'ignore)
+;; (defun emchat-v8-snac-cli-ssi-edit-begin (ectx &rest args)
+;; "Begin SSI edits. SNAC(#x13, #x11)."
+;; (emchat-v8-send ectx
+;; (emchat-v8-pack-snac ectx '(#x13 . #x11))))
+(defalias 'emchat-v8-snac-cli-ssi-edit-end #'ignore)
+;; (defun emchat-v8-snac-cli-ssi-edit-end (ectx &rest args)
+;; "End SSI edits. SNAC(#x13, #x12)."
+;; (emchat-v8-send ectx
+;; (emchat-v8-pack-snac ectx '(#x13 . #x12))))
+
+(defun emchat-v8-snac-cli-ssi-future-auth-grant (ectx uin reason)
+ "Give future auth grant. SNAC(#x13, #x14)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x13 . #x14)
+ (emchat-v8-pack-byte (length (number-to-string uin)))
+ (emchat-v8-pack-buin uin)
+ (emchat-v8-pack-dword 0))))
+
+(defun emchat-v8-snac-cli-ssi-del-yourself (ectx uin)
+ "Delete yourself from someone's contact list. SNAC(#x13, #x16)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x13 . #x16)
+ (emchat-v8-pack-buin uin))))
+
+(defun emchat-v8-snac-cli-ssi-send-auth-request (ectx uin msg)
+ "Send auth request. SNAC(#x13, #x18)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x13 . #x18)
+ (emchat-v8-pack-buin uin)
+ (emchat-v8-pack-bstr msg))))
+
+(defun emchat-v8-snac-cli-ssi-auth-reply (ectx uin reply &optional reason)
+ "Reply to auth-request. SNAC(#x13, #x1A)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x13 . #x1A)
+ (emchat-v8-pack-buin uin)
+ (emchat-v8-pack-byte reply)
+ (emchat-v8-pack-bstr reason)
+ (emchat-v8-pack-word 0))))
+
+
+(defun emchat-v8-snac-cli-setuserinfo (ectx)
+ "Send userinfo."
+ )
+
+(defconst emchat-v8-status-alist
+ `((offline . ,(* 256.0 256 256 256))
+ (invisible . #x100) ;user is invisible
+ (dnd . #x02) ;user does not want to be disturbed
+ (occupied . #x10) ;user is occupied
+ (na . #x04) ;user not available
+ (away . #x01) ;user is away
+ (ffc . #x20) ;user is free for chat
+ (online . #x00) ;user is online
+ (set-invisible . #x100)
+ (set-dnd . #x13)
+ (set-occupied . #x11)
+ (set-na . #x05)
+ (set-away . #x01)
+ (set-ffc . #x20)
+ (web-aware . #x010000)
+ (allow-ip . #x020000)
+ (birthday . #x80000)
+ (dcauth . #x10000000)
+ (dccontact . #x20000000))
+ "Alist of states.")
+
+(defun emchat-v8-find-status (num)
+ "Find statu by NUM."
+ (setq num (logand num #x0000ffff))
+ (let ((statuses (cdr emchat-v8-status-alist)))
+ (while (and statuses
+ (zerop (logand num (cdar statuses))))
+ (setq statuses (cdr statuses)))
+ (or (caar statuses) 'online)))
+
+(defun emchat-v8-snac-cli-setstatus (ectx &optional status)
+ "Set status, SNAC(1, 30)."
+ (setq status (apply 'logior
+ (mapcar #'(lambda (st)
+ (cdr (assoc st emchat-v8-status-alist)))
+ status)))
+
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x01 . #x1E)
+ (emchat-v8-pack-tlv 6
+ (emchat-v8-pack-dword status))
+ (emchat-v8-pack-tlv 8
+ (emchat-v8-pack-word 0)))))
+
+(defun emchat-v8-snac-cli-add-contact (ectx &optional contacts)
+ "CLI_ADDCONTACT, SNAC(3,4)
+Send either CONTACTS or ECTX's contact list."
+ (unless contacts
+ (setq contacts (emchat-v8-ctx-get-prop ectx 'contacts)))
+ (emchat-v8-debug "Adding contacts: %S" contacts)
+ (when contacts
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x03 . #x04)
+ (emchat-v8-pack-uinlist contacts)))))
+
+(defun emchat-v8-snac-cli-addvisible (ectx &optional uin-list)
+ "CLI_ADDVISIBLE SNAC(9, 5)."
+ (unless uin-list
+ (setq uin-list (emchat-v8-ctx-get-prop ectx 'visible-list)))
+ (emchat-v8-debug "Adding to visible: %S" uin-list)
+ (when uin-list
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x09 . #x05)
+ (emchat-v8-pack-uinlist uin-list)))))
+
+(defun emchat-v8-snac-cli-remvisible (ectx uin-list)
+ "CLI_ADDVISIBLE SNAC(9, 6)."
+ (emchat-v8-debug "Removing from visible: %S" uin-list)
+ (when uin-list
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x09 . #x06)
+ (emchat-v8-pack-uinlist uin-list)))))
+
+(defun emchat-v8-snac-cli-addinvisible (ectx &optional uin-list)
+ "CLI_ADDVISIBLE SNAC(9, 7)."
+ (unless uin-list
+ (setq uin-list (emchat-v8-ctx-get-prop ectx 'invisible-list)))
+ (emchat-v8-debug "Adding to invisible: %S" uin-list)
+ (when uin-list
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x09 . #x07)
+ (emchat-v8-pack-uinlist uin-list)))))
+
+(defun emchat-v8-snac-cli-reminvisible (ectx uin-list)
+ "CLI_REMINVISIBLE SNAC(9, 8)."
+ (emchat-v8-debug "Removing from invisible: %S" uin-list)
+ (when uin-list
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x09 . #x08)
+ (emchat-v8-pack-uinlist uin-list)))))
+
+(defun emchat-v8-snac-cli-keepalive (ectx)
+ "Send keep-alive flap."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-flap ectx 5)))
+
+(defun emchat-v8-pack-meta-snac (ectx sub &optional type &rest data)
+ "Create meta snac."
+ (setq data (apply 'concat data))
+
+ (let ((seq3 (emchat-v8-ctx-get-prop ectx 'our-seq3))
+ temp-data)
+ (if seq3
+ (emchat-v8-ctx-put-prop ectx 'our-seq3 (% (1+ seq3) 32767))
+ (emchat-v8-ctx-put-prop ectx 'our-seq3 2))
+
+ (setq temp-data
+ (concat
+ (emchat-v8-pack-uin (plist-get (emchat-v8-ctx-userinfo ectx) 'uin))
+ (emchat-v8-number->string-swap 2 sub)
+ (emchat-v8-number->string-swap 2 (emchat-v8-ctx-get-prop ectx 'our-seq3))
+ (when type
+ (emchat-v8-number->string-swap 2 type))
+ data))
+
+ (emchat-v8-pack-snac ectx '(#x15 . #x02)
+ (emchat-v8-pack-tlv 1
+ (emchat-v8-number->string-swap 2 (length temp-data))
+ temp-data))))
+
+(defun emchat-v8-snac-cli-reqofflinemsgs (ectx)
+ "CLI_REQOFFLINEMSGS, SNAC(15,2)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-meta-snac ectx 60)))
+
+(defun emchat-v8-snac-cli-metareqinfo (ectx uin)
+ "CLI_METAREQINFO, SNAC(15,2)/2000/1232."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-meta-snac ectx 2000 1232
+ (emchat-v8-pack-uin uin)))
+
+ ;; Save pair SEQ/UIN for later UIN extraction
+ (emchat-v8-ctx-put-prop ectx 'about-query-seq-uin
+ (cons (cons (emchat-v8-ctx-get-prop ectx 'our-seq3) uin)
+ (emchat-v8-ctx-get-prop ectx 'about-query-seq-uin))))
+
+(defun emchat-v8-snac-cli-searchbyuin (ectx uin)
+ "CLI_SEARCHBYUIN, SNAC(15,2)/2000/1385."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-meta-snac ectx 2000 1385
+ (emchat-v8-pack-word-le 310) ; Search key (310 == uin)
+ (emchat-v8-pack-lnts (emchat-v8-pack-uin uin)))))
+
+(defun emchat-v8-snac-cli-searchbyemail (ectx email)
+ "CLI_SEARCHBYEMAIL, SNAC(15,2)/2000/1395."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-meta-snac
+ ectx 2000 1395
+ (emchat-v8-pack-word-le 350) ; Search key (350 == email)
+ (emchat-v8-pack-llnts email))))
+
+(defun emchat-v8-snac-cli-searchbypersinf (ectx first last nick email online)
+ "CLI_SEARCHBYPERSINF, SNAC(15,2)/2000/1375."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-meta-snac
+ ectx 2000 1375
+ (emchat-v8-pack-word-le 320) ; Search key (320 == first name)
+ (emchat-v8-pack-llnts first)
+ (emchat-v8-pack-word-le 330) ; Search key (330 == last name)
+ (emchat-v8-pack-llnts last)
+ (emchat-v8-pack-word-le 340) ; Search key (340 == nick name)
+ (emchat-v8-pack-llnts nick)
+ (emchat-v8-pack-word-le 350) ; Search key (350 == email)
+ (emchat-v8-pack-llnts email)
+ (emchat-v8-pack-byte online))))
+
+;;; FIXME: this doesn't impliment direct connect or something called
+;;; "user kind"
+(defun emchat-v8-snac-cli-metasetsecurity (ectx auth web)
+ "CLI_METASETSECURITY. SNAC(#x15, #x02)/2000/1060."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-meta-snac
+ ectx 2000 1060
+ (emchat-v8-pack-byte auth) ; req auth 0 = no; 1 = yes
+ (emchat-v8-pack-byte web) ; webaware 0 = yes; 1 = no
+ (emchat-v8-pack-byte #x02) ; dc hard coded to only with auth
+ (emchat-v8-pack-byte 0)))) ; user kind (no idea, set to zero)
+
+(defun emchat-v8-snac-cli-ready (ectx)
+ "CLI_READY, SNAC(1, 2)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x01 . #x02)
+ (apply 'concat
+ (mapcar #'(lambda (sn)
+ (concat
+ (emchat-v8-pack-word (car sn))
+ (emchat-v8-pack-word (cdr sn))
+ (if (= (car sn) 2)
+ (emchat-v8-pack-dword #x0101047B)
+ (emchat-v8-pack-dword #x0110047B))))
+ emchat-v8-snacv-list)))))
+
+(defun emchat-v8-snac-cli-families (ectx)
+ "CLI_FAMILIES, SNAC(1, 17)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x01 . #x17)
+ (apply 'concat
+ (mapcar #'(lambda (sn)
+ (concat
+ (emchat-v8-pack-word (car sn))
+ (emchat-v8-pack-word (cdr sn))))
+ emchat-v8-snacv-list)))))
+
+(defun emchat-v8-snac-cli-ratesrequest (ectx)
+ "CLI_RATESREQUEST, SNAC(1, 6)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x01 . #x06))))
+
+(defun emchat-v8-snac-cli-reqinfo (ectx)
+ "CLI_REQINFO, SNAC(1, E)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x01 . #x0E))))
+
+(defun emchat-v8-snac-cli-reqlocation (ectx)
+ "CLI_REQLOCATION, SNAC(2, 2)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x02 . #x02))))
+
+(defun emchat-v8-snac-cli-reqbuddy (ectx)
+ "CLI_REQBUDDY, SNAC(3, 2)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x03 . #x02))))
+
+(defun emchat-v8-snac-cli-reqicbm (ectx)
+ "CLI_REQICBM, SNAC(4, 4)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x04 . #x04))))
+
+(defun emchat-v8-snac-cli-sendmsg (ectx uin format msg)
+ "CLI_SENDMSG, SNAC(4, 6).
+UIN - Icq uin to send message to.
+FORMAT - format id, 1 - simple, 2 - advanced, 4 - typed.
+MSG - Message itself."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x04 . #x06)
+ (emchat-v8-pack-dword 0) ; random
+ (emchat-v8-pack-dword 0) ; random
+ (emchat-v8-pack-word format)
+ (emchat-v8-pack-buin uin)
+ msg
+ (emchat-v8-pack-tlv 6))))
+
+(defconst emchat-v8-msg-encodings
+ '((us-ascii . 0)
+ (utf-16 . 2)
+ (8bit . 3)))
+
+(defun emchat-v8-send-simple-message (ectx uin message)
+ "Send simple message."
+ (emchat-v8-snac-cli-sendmsg ectx uin 1
+ (emchat-v8-pack-tlv 2
+ (emchat-v8-pack-tlv 1281 (emchat-v8-pack-byte 1))
+ (emchat-v8-pack-tlv 257
+ (emchat-v8-pack-word 3)
+ (emchat-v8-pack-word (+ 4 (length message)))
+ message))))
+
+(defun emchat-v8-send-typed-message (ectx uin type message)
+ "Send typed message."
+ (emchat-v8-snac-cli-sendmsg ectx uin 4
+ (emchat-v8-pack-tlv 5
+ (emchat-v8-pack-uin (plist-get (emchat-v8-ctx-userinfo ectx) 'uin))
+ (emchat-v8-pack-word-le
+ (car (find type emchat-v8-msg-types :key 'cdr :test 'eq)))
+ (emchat-v8-pack-lnts message))))
+
+(defun emchat-v8-send-advanced-message (ectx uin &rest add-arguments-here-for-advanced-message)
+ ;; Advanced message:
+ ;; TLV(5):
+ ;; 2 ACKTYPE : 0 - normal, 1 - abort, 2 - file ack
+ ;; 4 TIME : copy
+ ;; 4 ID : random id
+ ;; TLV(11) UNKNOWN : Only if ACTYPE is 1
+ ;; CAP
+ ;; TLV(10) ACKTYPE2 : 1 - normal, 2 - file ack
+ ;; TLV(5) PORT
+ ;; TLV(3) IP
+ ;; TLV15 UNKNOWN
+ ;; TLV(1001) MESSAGE
+; (emchat-v8-snac-cli-sendmsg ectx uin 2)
+ (emchat-v8-debug "TODO: `emchat-v8-send-advanced-message'")
+ )
+
+(defun emchat-v8-send-server-message (ectx uin &rest add-arguments-here-for-server-message)
+ ;; Server message:
+ ;; TLV(5)
+ ;; 4 UIN : sender uin
+ ;; 2 MSGTYPE : message type
+ ;; LNTS MSG : message with unspecified encoding
+; (emchat-v8-snac-cli-sendmsg ectx uin 3)
+ (emchat-v8-debug "TODO: `emchat-v8-send-advanced-message'")
+ )
+
+(defun emchat-v8-snac-cli-reqbos (ectx)
+ "CLI_REQBOS, SNAC(9, 2)."
+ (emchat-v8-send ectx
+ (emchat-v8-pack-snac ectx '(#x09 . #x02))))
+
+(defun emchat-v8-handle-flap (ectx-flap)
+ (let* ((ectx (car ectx-flap))
+ (flap (cdr ectx-flap))
+ (cid (emchat-v8-flap-cid flap)))
+ (cond ((= cid emchat-v8-FLAP-HELLO)
+ ;; XXX Login channel
+ (emchat-v8-debug "Got HELLO cid")
+ (let ((cmd (emchat-v8-fetch-dword (emchat-v8-flap-data flap)))
+ (cli-cook (emchat-v8-ctx-get-prop ectx 'cli-cookie)))
+ (cond ((= cmd 1)
+ (if cli-cook
+ ;; Already logged in, send Cookie
+ (emchat-v8-send ectx
+ (emchat-v8-pack-flap ectx emchat-v8-FLAP-HELLO
+ (emchat-v8-pack-dword 1)
+ (emchat-v8-pack-tlv 6 cli-cook)))
+
+ ;; Not logged in yet
+ (emchat-v8-login ectx)))
+
+ (t (error (format "Unknown FLAP CMD(%) in login channel." cmd))))
+ ))
+
+ ((= cid emchat-v8-FLAP-SNAC)
+ ;; SNAC channel
+ ;; TODO:
+ ;; - Write me
+ (let ((snac (emchat-v8-fetch-snac (emchat-v8-flap-data flap)))
+ (snacs emchat-v8-snac-list))
+ (while (and snacs
+ (or (not (= (emchat-v8-snac-family snac)
+ (car (caar snacs))))
+ (not (= (emchat-v8-snac-subtype snac)
+ (cdr (caar snacs))))))
+ (setq snacs (cdr snacs)))
+
+ (emchat-v8-debug "SNAC %S (%S)" snac (when (car snacs) (nth 1 (car snacs))))
+
+ (unless snacs
+ (error 'invalid-argument "Unknown SNAC" snac))
+
+ ;; Call snac handler
+ (funcall (nth 2 (car snacs))
+ ectx ; context
+ (emchat-v8-flap-data flap) ; data
+ (emchat-v8-snac-flags snac)))) ; snac flags
+
+ ((= cid emchat-v8-FLAP-ERRORS)
+ ;; ERRORS channel
+ (emchat-v8-debug "ERROR")
+ )
+
+ ((= cid emchat-v8-FLAP-LOGOFF)
+ ;; LOGOFF channel
+ (let* ((tlvs (emchat-v8-fetch-tlvs (emchat-v8-flap-data flap)))
+ (tlv (emchat-v8-tlv-get tlvs 5)))
+
+ (emchat-v8-debug "LOGOFF tlv_t5=%S" tlv)
+ ;; Close connection
+ (emchat-v8-close ectx)
+
+ (if (not tlv)
+ ;; Another user with same UIN
+ (emchat-v8-ctx-run-incoming-handler ectx 'logoff)
+
+ ;; Redirected
+ (let* ((nsrv (split-string (emchat-v8-tlv-str tlv) ":"))
+ (addr (nth 0 nsrv))
+ (port (string-to-int (nth 1 nsrv))))
+ (emchat-v8-debug "Redirected to new server: %s:%d" addr port)
+ ;; Store cookie and reconnect
+ (emchat-v8-ctx-put-prop ectx 'cli-cookie
+ (emchat-v8-tlv-str (emchat-v8-tlv-get tlvs 6)))
+ (emchat-v8-connect ectx addr port)))))
+
+ ((= cid emchat-v8-FLAP-PING)
+ ;; PING channel
+ (emchat-v8-debug "PING")
+ )
+
+ (t (error (format "Unknown FLAP cid(%d)." cid))))
+ ))
+
+(defun emchat-v8-fetch-handle-flaps (ectx)
+ (while (> (length (emchat-v8-ctx-incoming-buffer ectx)) 0)
+ ;; Do not do anything in filter function
+ (emchat-v8-handle-flap (cons ectx (emchat-v8-fetch-flap ectx)))))
+
+\f
+(defun emchat-v8-number->string (size val)
+ "Convert number value VAL to string of SIZE."
+ (cond ((= size 1)
+ (setq val (truncate val))
+ (char-to-string val))
+ ((= size 2)
+ (setq val (truncate val))
+ (concat (char-to-string (ash (mod val 65536) -8))
+ (char-to-string (logand val 255))
+ ))
+ ((= size 4)
+ ;; XXX remove this
+ (setq val (truncate val))
+ (mapconcat 'identity
+ (nreverse
+ (list (char-to-string (int-to-char (% val 256)))
+ (char-to-string (int-to-char (% (setq val (/ val 256)) 256)))
+ (char-to-string (int-to-char (% (setq val (/ val 256)) 256)))
+ (char-to-string (int-to-char (% (setq val (/ val 256)) 256)))
+ ))
+ ""))
+
+ (t (error "Invalid SIZE" size))))
+
+(defun emchat-v8-number->string-swap (size val)
+ "Convert number VAL to string of SIZE."
+ (let ((ss (emchat-v8-number->string size val))
+ tt)
+ (cond ((= size 2)
+ (setq tt (aref ss 0))
+ (aset ss 0 (aref ss 1))
+ (aset ss 1 tt))
+ ((= size 4)
+ (setq tt (aref ss 0))
+ (aset ss 0 (aref ss 3))
+ (aset ss 3 tt)
+ (setq tt (aref ss 1))
+ (aset ss 1 (aref ss 2))
+ (aset ss 2 tt)))
+ ss))
+
+(defun emchat-v8-create-message (&rest UNIPREFIX-message-spec)
+ "Create emchat message according to SPEC."
+ (let (UNIPREFIX-value-spec UNIPREFIX-value)
+ (mapconcat (lambda (UNIPREFIX-element)
+ (setq UNIPREFIX-value-spec (eval (aref UNIPREFIX-element 0)))
+ (setq UNIPREFIX-value (eval (aref UNIPREFIX-element 1)))
+
+ (cond ((numberp UNIPREFIX-value)
+ (emchat-v8-number->string UNIPREFIX-value-spec UNIPREFIX-value))
+ ((stringp UNIPREFIX-value)
+ (substring UNIPREFIX-value 0 UNIPREFIX-value-spec))
+ ((null UNIPREFIX-value)
+ (make-string UNIPREFIX-value-spec ?\x00))
+ (t (error "Invalid SPEC" UNIPREFIX-value-spec))))
+ UNIPREFIX-message-spec "")
+ ))
+
+(defun emchat-v8-string->number-le-flt (str &optional len)
+ "Convert STR to number."
+ (unless len
+ (setq len (length str)))
+
+ (let ((ret 0.0) (i 0))
+ (while (< i len)
+ (setq ret (+ ret (* (char-int (aref str i)) (expt 256.0 i)))
+ i (1+ i)))
+ ret))
+
+(defun emchat-v8-string->number-flt (str &optional len)
+ "Convert STR to number."
+ (unless len
+ (setq len (length str)))
+
+ (let ((ret 0.0) (i 0))
+ (while (< i len)
+ (setq ret (+ (* 256.0 ret) (char-int (aref str i)))
+ i (1+ i)))
+ ret))
+
+(defun emchat-v8-string->number-le-bigz (str &optional len)
+ "Convert STR to number."
+ ;; optimise for common cases
+ (cond ((eq len 4)
+ (+ (* (aref str 3) 16777216)
+ (* (aref str 2) 65536)
+ (* (aref str 1) 256)
+ (aref str 0)))
+ ((eq len 2)
+ (+ (* (aref str 1) 256)
+ (aref str 0)))
+ ((eq len 1)
+ (char-to-int (aref str 0)))
+ (t
+ (let* ((len (or len (length str)))
+ (ret (char-int (aref str 0)))
+ (i 1))
+ (while (< i len)
+ (setq ret (+ ret (* (char-int (aref str i))
+ (2^ (* 8 i))))
+ i (1+ i)))
+ ret))))
+
+(defun emchat-v8-string->number-bigz (str &optional len)
+ "Convert STR to number."
+ ;; optimise for common cases
+ (cond ((eq len 4)
+ (+ (* (aref str 0) 16777216)
+ (* (aref str 1) 65536)
+ (* (aref str 2) 256)
+ (aref str 3)))
+ ((eq len 2)
+ (+ (* (aref str 0) 256)
+ (aref str 1)))
+ ((eq len 1)
+ (char-to-int (aref str 0)))
+ (t
+ (let* ((len (or len (length str)))
+ (ret 0)
+ (i 0))
+ (while (< i len)
+ (setq ret (+ (lsh ret 8) (char-int (aref str i)))
+ i (1+ i)))
+ ret))))
+
+;; do the right thing at the right time, the wrong otherwise
+(cond
+ ((featurep 'bigz)
+ (defalias #'emchat-v8-string->number #'emchat-v8-string->number-bigz)
+ (defalias #'emchat-v8-string->number-le #'emchat-v8-string->number-le-bigz)
+ 'using-bigz)
+ (t
+ (defalias #'emchat-v8-string->number #'emchat-v8-string->number-flt)
+ (defalias #'emchat-v8-string->number-le #'emchat-v8-string->number-le-flt)
+ 'using-flt))
+
+(defvar emchat-v8-timeout 15
+ "Receive timeout in seconds.")
+
+(defun emchat-v8-grab-bytes (ectx len)
+ "Grab LEN bytes from ECTX's incoming buffer."
+ (setq len (truncate len)) ;for sure
+
+ (let (rstr)
+ (while (< (length (emchat-v8-ctx-incoming-buffer ectx)) len)
+ (when (null (accept-process-output (emchat-v8-ctx-proc ectx)
+ emchat-v8-timeout))
+ (error "EMCHAT: Timeout")))
+ (setq rstr (substring (emchat-v8-ctx-incoming-buffer ectx) 0 len))
+ (setf (emchat-v8-ctx-incoming-buffer ectx)
+ (substring (emchat-v8-ctx-incoming-buffer ectx) len))
+ rstr))
+
+(defun emchat-v8-grab-bytes-1 (vmsg len)
+ "Grab LEN bytes from VMSG."
+ (setq len (truncate len))
+
+ (let (rstr)
+ ;; Check LEN
+ (when (> len (length (aref vmsg 0)))
+ (error 'invalid-argument "Invalid len" len))
+
+ (setq rstr (substring (aref vmsg 0) 0 len))
+ (aset vmsg 0 (substring (aref vmsg 0) len))
+ rstr))
+
+;; Generic length storers
+(defvar emchat-v8-length-1 nil)
+(defvar emchat-v8-length-2 nil)
+(defvar emchat-v8-length-3 nil)
+(defvar emchat-v8-length-4 nil)
+
+(defun emchat-v8-parse-message (ectx-msg spec)
+ "Parse ECTX-MSG according to SPEC.
+ECTX-MSG is either EMchat context to grab bytes from, or string.
+
+SPEC is one of
+ - Vector specifies one value.
+ - List specifies multiple values.
+ - List of Lists specifies list of lists of multiple values."
+ (when (stringp ectx-msg)
+ (setq ectx-msg (vector ectx-msg)))
+
+ (let ((accessor (if (emchat-v8-ctx-p ectx-msg) 'emchat-v8-grab-bytes 'emchat-v8-grab-bytes-1))
+ vlen vtype rlist)
+
+ (cond ((vectorp spec)
+ ;; Vector
+ (setq vlen (truncate (eval (aref spec 0))))
+ (setq vtype (aref spec 1))
+ (if (numberp vtype)
+ (when (not (= (emchat-v8-string->number (funcall accessor ectx-msg vlen) vlen)
+ vtype))
+ (error 'invalid-argument "Invalid argument in MSG"))
+
+ ;; Normal type
+ (cond ((or (eq vtype 'number) (eq vtype 'integer))
+ (setq rlist (emchat-v8-string->number (funcall accessor ectx-msg vlen) vlen)))
+
+ ((or (eq vtype 'number-swap) (eq vtype 'integer-swap))
+ (setq rlist (emchat-v8-string->number-le (funcall accessor ectx-msg vlen) vlen)))
+
+ ((eq vtype 'string)
+ (setq rlist (funcall accessor ectx-msg vlen)))
+
+ ((and (symbolp vtype) (not (keywordp vtype))
+ (member vtype '(emchat-v8-length-1 emchat-v8-length-2 emchat-v8-length-3 emchat-v8-length-4)))
+ ;; If symbol - set it
+ (set vtype (emchat-v8-string->number (funcall accessor ectx-msg vlen) vlen))
+ (setq rlist (symbol-value vtype)))
+
+ ((listp vtype)
+ (setq rlist (mapcar #'(lambda (not-used)
+ (emchat-v8-parse-message ectx-msg vtype))
+ (make-list vlen nil))))
+
+ ((null vtype) ;; Skip
+ )
+
+ (t (error 'invalid-argument "Invalid type in SPEC" vtype)))))
+
+ ((and (listp spec)
+ (not (member nil (mapcar (lambda (l) (listp l)) spec))))
+ ;; List of Lists
+ )
+
+ ((listp spec)
+ ;; List
+ (setq rlist (mapcar (lambda (e) (emchat-v8-parse-message ectx-msg e)) spec)))
+
+ (t (error 'invalid-argument "Invalid SPEC" spec)))
+
+ rlist))
+
+
+(put 'emchat-v8-parse-message 'lisp-indent-function 1)
+
+(defun emchat-v8-fetch-data (data len)
+ (vector (funcall (if (emchat-v8-ctx-p data)
+ 'emchat-v8-grab-bytes
+ 'emchat-v8-grab-bytes-1)
+ data len)))
+
+(defun emchat-v8-fetch-string (data &optional len)
+ (aref (emchat-v8-fetch-data data (or len (length (aref data 0)))) 0))
+
+(defun emchat-v8-fetch-byte (data)
+ (char-to-int (string-to-char (emchat-v8-fetch-string data 1))))
+(defun emchat-v8-pack-byte (byte)
+ (char-to-string byte))
+
+(defun emchat-v8-fetch-word (data)
+ (truncate (emchat-v8-string->number
+ (emchat-v8-fetch-string data 2))))
+(defun emchat-v8-pack-word (word)
+ (emchat-v8-number->string 2 word))
+
+(defun emchat-v8-fetch-word-le (data)
+ (truncate (emchat-v8-string->number-le
+ (emchat-v8-fetch-string data 2))))
+(defun emchat-v8-pack-word-le (word)
+ (emchat-v8-number->string-swap 2 word))
+
+(defun emchat-v8-fetch-dword (data)
+ (emchat-v8-string->number
+ (emchat-v8-fetch-string data 4)))
+(defun emchat-v8-pack-dword (dword)
+ (emchat-v8-number->string 4 dword))
+
+(defun emchat-v8-fetch-time (data)
+ (cons (emchat-v8-fetch-word data)
+ (emchat-v8-fetch-word data)))
+
+(defun emchat-v8-pack-time (time)
+ (concat
+ (emchat-v8-pack-word (car time))
+ (emchat-v8-pack-word (cdr time))))
+
+(defun emchat-v8-fetch-uin (data)
+ (truncate
+ (emchat-v8-string->number-le
+ (emchat-v8-fetch-string data 4))))
+
+(defun emchat-v8-fetch-uinlist (count uinlist)
+ (let (result)
+ (dotimes (i count)
+ (append (emchat-v8-fetch-uin uinlist) result))))
+
+(defun emchat-v8-pack-uin (uin)
+ (emchat-v8-number->string-swap 4 uin))
+
+(defun emchat-v8-fetch-buin (data)
+ "Fetch BUIN and return uin number."
+ (string-to-number (emchat-v8-fetch-string data (emchat-v8-fetch-byte data))))
+(defun emchat-v8-pack-buin (uin)
+ (let ((suin (number-to-string uin)))
+ (concat (emchat-v8-pack-byte (length suin)) suin)))
+
+(defun emchat-v8-fetch-bstr (data)
+ (let* ((len (emchat-v8-fetch-word data))
+ (str (emchat-v8-fetch-string data len)))
+ (substring str 0 len)))
+
+(defun emchat-v8-pack-bstr (str)
+ (concat (emchat-v8-pack-word (length str)) str))
+
+;; Various packers
+(defun emchat-v8-pack-uinlist (uin-list)
+ (apply 'concat (mapcar 'emchat-v8-pack-buin uin-list)))
+
+(defun emchat-v8-pack-nts (string)
+ (concat string (char-to-string 0)))
+
+(defun emchat-v8-pack-lnts (string)
+ (let ((nts (emchat-v8-pack-nts string)))
+ (concat
+ (emchat-v8-pack-word-le (length nts))
+ nts)))
+
+(defun emchat-v8-pack-llnts (string)
+ (let ((nts (emchat-v8-pack-nts string)))
+ (concat
+ (emchat-v8-pack-word-le (+ (length nts) 2))
+ (emchat-v8-pack-word-le (length nts))
+ nts)))
+
+(defun emchat-v8-fetch-lnts (data)
+ (let* ((len (emchat-v8-fetch-word-le data))
+ (str (emchat-v8-fetch-string data len)))
+ (substring str 0 (1- len))))
+
+;; FLAP
+(defun emchat-v8-fetch-flap (data)
+ "Get next queued FLAP from emchat context ECTX."
+ (set-process-filter
+ (emchat-v8-ctx-proc data) 'emchat-v8-proc-filter-accumulator)
+
+ (unwind-protect
+ (progn
+ (let ((bb (emchat-v8-fetch-byte data)))
+ (unless (= bb #x2A)
+ (error "Unexpected data while fetching FLAP")))
+
+ (let* ((cin (emchat-v8-fetch-byte data))
+ (seq (emchat-v8-fetch-word data))
+ (flen (emchat-v8-fetch-word data))
+ (fdata (emchat-v8-fetch-data data flen)))
+ (list cin seq fdata)))
+
+ (set-process-filter
+ (emchat-v8-ctx-proc data) 'emchat-v8-proc-filter-proccessing)))
+
+(defun emchat-v8-pack-flap (ectx chan-id &rest flap-data)
+ "Create FLAP packet of channel id CHAN-ID and DATA."
+ (setq flap-data (apply 'concat flap-data))
+
+ (prog1
+ (concat
+ (emchat-v8-pack-byte #x2A)
+ (emchat-v8-pack-byte chan-id)
+ (emchat-v8-pack-word (emchat-v8-ctx-sequence ectx))
+ (emchat-v8-pack-word (length flap-data))
+ flap-data)
+
+ ;; Increase sequence number
+ (incf (emchat-v8-ctx-sequence ectx))
+ (when (> (emchat-v8-ctx-sequence ectx) 65535)
+ (setf (emchat-v8-ctx-sequence ectx)
+ (% (emchat-v8-ctx-sequence ectx) 65536)))))
+(put 'emchat-v8-pack-flap 'lisp-indent-function 2)
+
+;; SNAC
+(defun emchat-v8-fetch-snac (data)
+ "Get next SNAC."
+ (let ((family (emchat-v8-fetch-word data))
+ (subtype (emchat-v8-fetch-word data))
+ (flags (emchat-v8-fetch-word data))
+ (rid (emchat-v8-fetch-dword data)))
+
+ ;; If 15th bit is set in FLAGS then DATA contains some additional
+ ;; data in format LENGTH [WORD], DATA [LENGTH]
+ (unless (zerop (logand flags 32768))
+ (let ((len (emchat-v8-fetch-word data)))
+ (emchat-v8-fetch-data data len)))
+
+ (list family subtype flags rid)))
+
+(defun emchat-v8-pack-snac (ectx family-subtype &rest snac-data)
+ "Create SNAC packet."
+ (setq snac-data (apply 'concat snac-data))
+ (emchat-v8-pack-flap ectx 2
+ (emchat-v8-pack-word (car family-subtype))
+ (emchat-v8-pack-word (cdr family-subtype))
+ (emchat-v8-pack-word 0) ; XXX flags
+ (emchat-v8-pack-dword 0) ; XXX rid
+ snac-data))
+(put 'emchat-v8-pack-snac 'lisp-indent-function 2)
+
+;; TLVs
+(defun emchat-v8-fetch-single-tlv (data)
+ (let* ((type (emchat-v8-fetch-word data))
+ (len (emchat-v8-fetch-word data))
+ (value (emchat-v8-fetch-data data len)))
+ (list type len value)))
+
+(defun emchat-v8-fetch-tlvs (data)
+ "From VMSG extract TLV list."
+ (let ((tlvs nil))
+ (while (> (length (aref data 0)) 0)
+ (setq tlvs (cons (emchat-v8-fetch-single-tlv data) tlvs)))
+ (nreverse tlvs)))
+
+(defun emchat-v8-fetch-n-tlvs (data n)
+ "Read TLVs of total length N and return a list."
+ (let ((tlvs nil))
+ (while (> n 0)
+ (let* ((tlv (emchat-v8-fetch-single-tlv data)))
+ (setq n (- n (emchat-v8-tlv-len tlv) 4)
+ tlvs (cons tlv tlvs))))
+ (nreverse tlvs)))
+
+(defun emchat-v8-tlv-get (tlv-list type)
+ "From TLV list TLV-LIST get tlv of TYPE."
+ (while (and tlv-list (not (= (emchat-v8-tlv-type (car tlv-list)) type)))
+ (setq tlv-list (cdr tlv-list)))
+ (car tlv-list))
+
+(defun emchat-v8-pack-tlv (type &rest values)
+ "Create TLV."
+ (let ((val (apply 'concat values)))
+ (concat
+ (emchat-v8-pack-word type)
+ (emchat-v8-pack-word (length val))
+ val)))
+(put 'emchat-v8-pack-tlv 'lisp-indent-function 1)
+
+\f
+(defun emchat-v8-login (ectx &optional uin password)
+ "In ECTX context send UIN/PASSWORD to ICQ server."
+ (emchat-v8-debug "Logging in ..")
+
+ (unless uin
+ (setq uin (plist-get (emchat-v8-ctx-userinfo ectx) 'uin)))
+ (unless password
+ (setq password (plist-get (emchat-v8-ctx-userinfo ectx) 'password)))
+
+ ;; Remove password (for somekind of security)
+ (setf (emchat-v8-ctx-userinfo ectx)
+ (plist-remprop (emchat-v8-ctx-userinfo ectx) 'password))
+
+ (emchat-v8-send ectx
+ (emchat-v8-pack-flap ectx emchat-v8-FLAP-HELLO
+ (emchat-v8-pack-dword 1)
+ (emchat-v8-pack-tlv 1
+ (number-to-string uin))
+ (emchat-v8-pack-tlv 2 (emchat-v8-util-encrypt password))
+ (emchat-v8-pack-tlv 3 emchat-v8-client-id-string)
+ (emchat-v8-pack-tlv #x16
+ (emchat-v8-pack-word #x010A))
+ (emchat-v8-pack-tlv #x17
+ (emchat-v8-pack-word emchat-v8-FLAP-VER-MAJOR))
+ (emchat-v8-pack-tlv #x18
+ (emchat-v8-pack-word emchat-v8-FLAP-VER-MINOR))
+ (emchat-v8-pack-tlv #x19
+ (emchat-v8-pack-word emchat-v8-FLAP-VER-LESSER))
+ (emchat-v8-pack-tlv #x1A
+ (emchat-v8-pack-word emchat-v8-FLAP-VER-BUILD))
+ (emchat-v8-pack-tlv #x14
+ (emchat-v8-pack-dword emchat-v8-FLAP-VER-SUBBUILD))
+ (emchat-v8-pack-tlv #x0F "en")
+ (emchat-v8-pack-tlv #x0E "us"))))
+
+\f
+(provide 'emchat-v8)
+
+;;; emchat-v8.el ends here
--- /dev/null
+;;; emchat-wharf.el --- DockApp/status window for EMchat
+
+;; Copyright (C) 2001 - 2008 Steve Youngs, Erik Arneson
+
+;; Author: Erik Arneson <erik@aarg.net>
+;; Maintainer: Erik Arneson <erik@aarg.net>
+;; Created: Aug 10, 2001
+;; Homepage: http://www.emchat.org/
+;; Keywords: comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(defvar emchat-wharf-frame nil
+ "Frame in which EMchatWharf is running.")
+
+(defvar emchat-wharf-frame-props
+ '((name . "EMchatWharf")
+ (height . 5)
+ (width . 8)
+ (unsplittable . t)
+ (minibuffer . none)
+ (menubar-visible-p . nil)
+ (has-modeline-p . nil)
+ (default-gutter-visible-p . nil)
+ (default-toolbar-visible-p . nil)
+ (scrollbar-height . 0)
+ (scrollbar-width . 0)
+ (text-cursor-visible-p . nil))
+ "Frame properties for EMchatWharf.")
+
+(defvar emchat-wharf-buf nil
+ "Buffer in which EMchatWharf is running.")
+
+(defgroup emchat-wharf nil
+ "Miniature EMchat status window."
+ :prefix "emchat-wharf-"
+ :group 'emchat)
+
+(defface emchat-wharf-default-face
+ '((((class color))
+ (:foreground "Green" :family "fixed" :size "9pt"))
+ (t
+ (:family "fixed" :size "9pt")))
+ "Face used in EMchatWharf window.
+
+If you want this to be dockable, make sure you use a small but readable
+font."
+ :group 'emchat-wharf)
+
+(defcustom emchat-wharf-notice-riece-flag nil
+ "When non-nil, indicate Riece activity in EMchatWharf.
+
+This requires riece-biff to be set up and active."
+ :type 'boolean
+ :group 'emchat-wharf)
+
+;; Riece activity indicator face
+(make-face 'emchat-wharf-riece-active-face
+ "Face used in EMchat Wharf when there is activity from Riece.")
+(set-face-parent 'emchat-wharf-riece-active-face
+ 'emchat-wharf-default-face)
+(set-face-foreground 'emchat-wharf-riece-active-face "Red")
+
+(make-face 'emchat-wharf-riece-inactive-face
+ "Face used in EMchat Wharf when there is no activity from Riece.")
+(set-face-parent 'emchat-wharf-riece-inactive-face
+ 'emchat-wharf-default-face)
+(set-face-foreground 'emchat-wharf-riece-inactive-face "Black")
+
+
+;;;###autoload
+(defcustom emchat-wharf-frame-use-p nil
+ "If non-NIL, start up the EMchatWharf mini-frame."
+ :type 'boolean
+ :group 'emchat-wharf
+ :tag "EMchatWharf mini-frame")
+
+;;; Internal variables
+
+;;; Riece integration
+(defvar emchat-riece-activity nil
+ "This is non-nil when riece-biff has been triggered.")
+
+;; Advise a couple of Riece functions to run some hooks for us.
+(defadvice riece-biff-after-display-message-function (after biffon (&rest args) activate)
+ "Update the EMchatWharf Riece indicator."
+ (when (eq riece-biff-mode-string 'riece-biff-biff-mode-string)
+ (run-hooks 'riece-biff-activity-hook)))
+
+(defadvice riece-biff-clear (after biffoff (&rest args) activate)
+ "Update the EMchatWharf Riece indicator."
+ (when (eq riece-biff-mode-string 'riece-biff-default-mode-string)
+ (run-hooks 'riece-biff-clear-hook)))
+
+(defun emchat-wharf-riece-active ()
+ "Make the EMchatWharf Riece indicator active."
+ (let ((emchat-riece-activity t))
+ (emchat-wharf-update-riece)))
+
+(defun emchat-wharf-riece-inactive ()
+ "Make the EMchatWharf Riece indicator inactive."
+ (let ((emchat-riece-activity nil))
+ (emchat-wharf-update-riece)))
+
+(defun emchat-wharf-update-riece ()
+ "Update the status line in EMchatWharf."
+ (when emchat-wharf-buf
+ (save-excursion
+ (set-buffer emchat-wharf-buf)
+ (goto-line 4)
+ (delete-region (point-at-bol) (point-at-eol))
+ (insert-face "Riece" (if emchat-riece-activity
+ 'emchat-wharf-riece-active-face
+ 'emchat-wharf-riece-inactive-face)))))
+
+;;;###autoload
+(defun emchat-wharf-new-frame ()
+ "Create new EMchatWharf frame."
+ (unless (frame-live-p emchat-wharf-frame)
+ (setq emchat-wharf-frame (new-frame emchat-wharf-frame-props))
+ (select-frame emchat-wharf-frame)
+ (unless (buffer-live-p emchat-wharf-buf)
+ (setq emchat-wharf-buf (get-buffer-create "*EMchatWharf*"))
+ (set-buffer-dedicated-frame emchat-wharf-buf emchat-wharf-frame)
+ (save-excursion
+ (set-buffer emchat-wharf-buf)
+ (insert "New 000\nSys 000\n")
+ (set-extent-face (make-extent (point-min) (point-max) emchat-wharf-buf)
+ 'emchat-wharf-default-face)
+ (insert-face emchat-user-status (emchat-status-face emchat-user-status))
+ (when emchat-wharf-notice-riece-flag
+ (insert "\n")
+ (insert-face "Riece" (if emchat-riece-activity
+ 'emchat-wharf-riece-active-face
+ 'emchat-wharf-riece-inactive-face)))
+ ))
+ (if (fboundp 'set-specifier)
+ (progn
+ (set-specifier horizontal-scrollbar-visible-p nil
+ (cons emchat-wharf-frame nil))
+ (set-specifier vertical-scrollbar-visible-p nil
+ (cons emchat-wharf-frame nil))))
+ (set-face-font 'default
+ (face-font-name 'emchat-wharf-default-face)
+ emchat-wharf-frame)
+ (set-window-buffer nil emchat-wharf-buf)))
+
+(defun emchat-wharf-change-messages (type num)
+ (let (oldnum newnum)
+ (if emchat-wharf-buf
+ (save-excursion
+ (set-buffer emchat-wharf-buf)
+ (goto-char (point-min))
+ (if (re-search-forward (concat "^\\("
+ type
+ " *\\([0-9]+\\)\\)$")
+ nil t)
+ (progn
+ (setq oldnum (string-to-int (match-string 2))
+ newnum (+ oldnum num))
+ (if (> 0 newnum)
+ (setq newnum 0))
+ (replace-match (format "%-3s %03d" type newnum))))))))
+
+(defun emchat-wharf-inc-messages ()
+ "Increment number of new messages in EMchatWharf."
+ (emchat-wharf-change-messages "New" 1))
+
+(defun emchat-wharf-dec-messages ()
+ "Decrement number of new messages in EMchatWharf."
+ (emchat-wharf-change-messages "New" -1))
+
+(defun emchat-wharf-inc-system ()
+ "Increment number of system messages in EMchatWharf."
+ (emchat-wharf-change-messages "Sys" 1))
+
+(defun emchat-wharf-dec-system ()
+ "Decrement number of system messages in EMchatWharf."
+ (emchat-wharf-change-messages "Sys" -1))
+
+(defun emchat-wharf-update-status ()
+ "Update the status line in EMchatWharf."
+ (when emchat-wharf-buf
+ (save-excursion
+ (set-buffer emchat-wharf-buf)
+ (goto-line 3)
+ (delete-region (point-at-bol) (point-at-eol))
+ (insert-face emchat-user-status (emchat-status-face emchat-user-status)))))
+
+(provide 'emchat-wharf)
+;;; emchat-wharf.el ends here
--- /dev/null
+;;; emchat-world.el --- EMchat contact list management
+
+;; Copyright (C) 2002 - 2007 Steve Youngs
+
+;; Author: Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created: 2002-10-01
+;; Homepage: http://www.emchat.org/
+;; Keywords: comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+
+(eval-and-compile
+ (require 'emchat-meta)
+ (require 'emchat-menu))
+
+(autoload 'emchat-search-by-uin "emchat" nil t)
+(autoload 'emchat-buddy-show-buffer "emchat-buddy" nil t)
+(autoload 'emchat-process-alias-input "emchat")
+(autoload 'emchat-buddy-update-face "emchat-buddy")
+(autoload 'emchat-completing-aliases "emchat")
+(autoload 'emchat-valid-uin-p "emchat")
+
+(eval-when-compile
+ (require 'font-lock)
+ (require 'sort))
+
+(defcustom emchat-world-rc-filename (expand-file-name "world" emchat-directory)
+ "*Filename for resource file."
+ :type 'file
+ :group 'emchat-info)
+
+(defcustom emchat-recently-added-by-filename
+ (expand-file-name "recent-adds" emchat-directory)
+ "*File containing UIN's of people who have added you to their list."
+ :type 'file
+ :group 'emchat-info)
+
+(defcustom emchat-world-track-all-adds nil
+ "*When non-nil, every UIN of people adding you is tracked.
+
+The default, nil, means that only people who are not in your contact
+list will be tracked."
+ :type 'boolean
+ :group 'emchat-info)
+
+(defvar emchat-world-recently-added-by nil
+ "Contains the UIN's of anyone who adds you to their list.
+
+This is for the current session only. But these people are saved in
+`emchat-recently-added-by-filename' for future reference.")
+
+;;; Internal variables
+
+(defcustom emchat-user-alias "me"
+ "*Your alias in `emchat-world'.
+Run `emchat-world-update' after modifying this variable."
+ :group 'emchat-info)
+
+(defvar emchat-user-bin nil
+ "User alias in binary string.
+The mere purpose is to speed up operations.
+Updated by `emchat-world-update'.")
+
+(defvar emchat-all-uin nil
+ "All uin in `emchat-world'.
+The mere purpose is to speed up operations.
+Updated by `emchat-world-update'.")
+
+(defvar emchat-world nil
+ "List of alias, uin, and plist.")
+
+(defvar emchat-all-aliases nil
+ "All aliases in `emchat-world'.
+The mere purpose is to speed up operations.
+Updated by `emchat-world-update'.")
+
+(defvar emchat-add-user-p nil)
+(defvar emchat-new-buddy nil)
+(defvar emchat-world-new-user-hash nil)
+
+(eval-and-compile
+ (unless (featurep 'sxemacs)
+ (defalias #'defregexp #'defconst)))
+
+(defregexp emchat-world-ssi-LastUpdateTime-regexp
+ (if (featurep '(or sxemacs raw-strings))
+ #r"^::LastUpdateTime:\s-(\([0-9]+\)\s-.\s-\([0-9]+\))$"
+ "^::LastUpdateTime:\\s-(\\([0-9]+\\)\\s-.\\s-\\([0-9]+\\))$")
+ "Regular expression to match the last update time in world.")
+
+(defregexp emchat-world-ssi-count-regexp
+ (if (featurep '(or sxemacs raw-strings))
+ #r"^::Count:\s-\(.*\)$"
+ "^::Count:\\s-\\(.*\\)$")
+ "Regular expression to match the entries count in world.")
+
+(defregexp emchat-world-ssi-id-regexp
+ (if (featurep '(or sxemacs raw-strings))
+ #r"\(?:[ ]{SSIgrp=\([0-9]+\)[ ]SSIid=\([0-9]+\)}\)"
+ "\\(?:[ ]{SSIgrp=\\([0-9]+\\)[ ]SSIid=\\([0-9]+\\)}\\)")
+ "Regular expression matching SSI id numbers in world.")
+
+(defregexp emchat-world-rc-regexp
+ (if (featurep '(or sxemacs raw-strings))
+ #r"^:icq[ ]+\([0-9]+\)[ ]+\([^:]+?\)[ ]?\(:.*\)*$"
+ "^:icq[ ]+\\([0-9]+\\)[ ]+\\([^:]+?\\)[ ]?\\(:.*\\)*$")
+ "Regular expression for rc file.
+Format: :icq uin alias group(s)
+Group is prefixed by a colon :. Anything between uin and group including
+white spaces is alias. For example,
+
+:icq 409533 fire :linux :emchat
+:icq 123456 the hatter :unreal
+
+The regexp paren groupings are as follows:
+
+ 1 -- UIN
+ 2 -- Alias
+ 3 -- groups \(local, not SSI\)")
+
+(defun emchat-world-ssi-mod-time ()
+ "Extract and return the last update time from local copy of SSI.
+
+This time is kept in `emchat-world-rc-filename', if it doesn't exist,
+return zero."
+ (let ((modt (cons 0 0)))
+ (with-current-buffer (find-file-noselect emchat-world-rc-filename)
+ (goto-char (point-max))
+ (when (re-search-backward emchat-world-ssi-LastUpdateTime-regexp nil t)
+ (setq modt (cons (string-to-number (match-string 1))
+ (string-to-number (match-string 2)))))
+ modt)))
+
+(defun emchat-world-ssi-count ()
+ "Extract and return the item count from local copy of SSI.
+
+This count is kept in `emchat-world-rc-filename', if it doesn't exist,
+return zero."
+ (let ((count 0))
+ (with-current-buffer (find-file-noselect emchat-world-rc-filename)
+ (goto-char (point-max))
+ (when (re-search-backward emchat-world-ssi-count-regexp nil t)
+ (setq count (string-to-number (match-string 1))))
+ count)))
+
+(defun emchat-world-update-world-count (count time)
+ "Update the entries COUNT and LastUpdateTime TIME in world."
+ (with-current-buffer (find-file-noselect emchat-world-rc-filename)
+ (goto-char (point-max))
+ (condition-case nil
+ (progn
+ (save-excursion
+ (re-search-backward emchat-world-ssi-LastUpdateTime-regexp)
+ (replace-string
+ (substring (match-string 0)
+ (- (+ 5 (length (match-string 1))
+ (length (match-string 2)))))
+ (format "%S" time)))
+ (re-search-backward emchat-world-ssi-count-regexp)
+ (replace-string (match-string 1) (format "%d" count)))
+ ;; count/time markers don't exist, add em.
+ (t
+ (goto-char (point-at-bol))
+ (insert (format "::Count: %d\n" count)
+ (format "::LastUpdateTime: %S" time))))
+ (save-buffer)
+ (kill-buffer nil)))
+
+(defun emchat-world-ssi-grp ()
+ "Return the first non-zero SSI group ID to use for new contacts."
+ (let ((buf (find-file-noselect emchat-world-rc-filename))
+ (id nil))
+ (with-current-buffer buf
+ (goto-char (point-min))
+ (while (not id)
+ (re-search-forward emchat-world-ssi-id-regexp nil t)
+ (unless (zerop (string-to-number (match-string 1)))
+ (setq id (string-to-number (match-string 1))))))
+ id))
+
+(defun emchat-world-next-ssi-id ()
+ "Return the next server side contact ID number."
+ (let ((buf (find-file-noselect emchat-world-rc-filename))
+ (idlist nil))
+ (with-current-buffer buf
+ (goto-char (point-min))
+ (while (re-search-forward emchat-world-ssi-id-regexp nil t)
+ (push (string-to-number (match-string 2)) idlist)))
+ (1+ (apply #'max idlist))))
+
+(defun emchat-world-sync-ssi-maybe (uin grpid id alias)
+ "Possibly synchronise entries from SSI to local world.
+
+UIN is the UIN of the contact.
+GRPID is the SSI group id number \(needed for modifying/deleting\).
+ID is the SSI id of this contact \(needed for modifying/deleting\).
+ALIAS is the \"nick\" of the contact as listed in your SSI.
+
+Note that you shouldn't call this function directly, it doesn't
+save any changes it makes to your world file. That is done by
+`emchat-v8-snac-srv-ssi-reply', which calls this."
+ (let ((world (find-file-noselect emchat-world-rc-filename))
+ (known-uin (member (emchat-stringular-uin uin) emchat-all-uin)))
+ (with-current-buffer world
+ (goto-char (point-min))
+ (if known-uin
+ (when (re-search-forward (regexp-quote (emchat-stringular-uin uin)))
+ (if (re-search-forward emchat-world-ssi-id-regexp (point-at-eol) t)
+ (progn
+ (or (= grpid (string-to-number (match-string 1)))
+ (replace-match (match-string 1) (format "%s" grpid)))
+ (or (= id (string-to-number (match-string 2)))
+ (replace-match (match-string 2) (format "%s" id))))
+ (goto-char (point-at-eol))
+ (insert (format " {SSIgrp=%s SSIid=%s}" grpid id))))
+ (or (and (re-search-forward emchat-world-ssi-count-regexp nil t)
+ (forward-line -1))
+ (goto-char (point-max)))
+ (insert (format "\n:icq %s %s {SSIgrp=%s SSIid=%s}\n"
+ uin (aref alias 0) grpid id))
+ (emchat-add-new-user-to-buddy-buffer
+ (emchat-stringular-uin uin) (aref alias 0))))))
+
+(defun emchat-world-add-new-user ()
+ "Add a new user to world."
+ (let ((uin (gethash :uin emchat-world-new-user-hash))
+ (nick (gethash :nick emchat-world-new-user-hash))
+ (ssi-grp (gethash :ssi-grp emchat-world-new-user-hash))
+ (id (gethash :id emchat-world-new-user-hash))
+ (egrps (gethash :egrps emchat-world-new-user-hash))
+ (status (gethash :status emchat-world-new-user-hash)))
+ (set-buffer
+ (find-file-noselect (expand-file-name emchat-world-rc-filename)))
+ (goto-char (point-max))
+ (if (re-search-backward emchat-world-ssi-count-regexp nil t)
+ (progn
+ (insert (format ":icq %d %s %s {SSIgrp=%d SSIid=%d}\n\n"
+ uin nick egrps ssi-grp id))
+ (save-buffer (current-buffer))
+ (kill-buffer (current-buffer))
+ ;; Inform the user in the log.
+ (emchat-log-info
+ (emchat-decode-string
+ (format "Alias: %s, UIN: %d added to contact list."
+ nick uin)))
+ (emchat-add-new-user-to-buddy-buffer
+ (emchat-stringular-uin uin) nick status))
+ (emchat-log-error "Malformed world file"))))
+
+(defun emchat-add-new-user-to-buddy-buffer (uin nick &optional status)
+ "Push the nick name from `emchat-add-user' into the buddy buffer.
+Sort of a cut-down version or `emchat-world-update'"
+ (if (member uin emchat-all-uin)
+ (emchat-log-error "%s is already in your contact list" nick)
+ (if (or (null status)
+ (and (eq status 'online)
+ (not (eq emchat-buddy-view 'emchat-active-aliases)))
+ (and (eq status 'offline)
+ (eq emchat-buddy-view 'emchat-all-aliases)))
+ (add-to-list (symbol-value 'emchat-buddy-view) nick))
+
+ (let* ((bhelp (format "%s (%s)\n\n Status: %s\n Groups: %s\nHistory: %s\n"
+ nick
+ uin
+ (or (emchat-world-getf nick 'status) "offline")
+ (or (emchat-world-getf nick 'group) "none")
+ (or (emchat-world-getf nick 'history) "none"))))
+ (set-extent-properties
+ (make-extent 0 (length nick) nick)
+ `(highlight t duplicable t start-open t keymap ,emchat-alias-map
+ balloon-help ,bhelp)))
+ (save-excursion
+ (set-buffer (find-file-noselect emchat-world-rc-filename))
+ (goto-char (point-max))
+ (search-backward-regexp emchat-world-rc-regexp nil t)
+ (let* ((buddy (list nick uin 'rc-index (point))))
+ (push buddy emchat-world)))
+ (setq emchat-all-aliases (mapcar 'first emchat-world))
+ (setq emchat-all-uin (mapcar 'second emchat-world))
+ (emchat-buddy-show-buffer 'new 'no-select)
+ (setq emchat-add-user-p nil)))
+
+;;; Code - group:
+
+(defun emchat-group-put (group name)
+ "Put something into GROUP.
+NAME can be either an alias or another group name."
+ (let ((list (assoc group emchat-world)))
+ (cond
+ (list
+ (setcdr list (list (pushnew name (cadr list) :test 'equal))))
+ (t
+ (push (list group (list name)) emchat-world)))))
+
+(defun emchat-group-get (group)
+ "Get members from GROUP."
+ (cadr (assoc group emchat-world)))
+
+(defun emchat-group-get-all-aliases (group)
+ "Recursively get all aliases from GROUP."
+ (loop for x in (emchat-group-get group)
+ as expanded-x = (emchat-group-get x)
+ if (atom expanded-x) collect x
+ else append (emchat-group-get-all-aliases x)))
+
+(defun emchat-group-select-aliases (state &rest aliases)
+ "Select aliases and update buddy buffer.
+Nil STATE means deselect, 'toggle means invert current state, and other
+non-nil means select.
+
+See `emchat-process-alias-input'."
+ (interactive '(select))
+ (emchat-process-alias-input 'aliases)
+ (loop for x in aliases
+ do (when (eq state 'toggle)
+ (setq state (not (emchat-world-getf x 'selected))))
+ do (emchat-world-putf x 'selected state)
+ do (emchat-buddy-update-face x))
+ (emchat-buddy-show-buffer 'new 'noselect))
+
+(defun emchat-world-getf (alias tag)
+ "For ALIAS get property of TAG.
+If TAG is 'all, return the plist."
+ (let ((plist (cddr (assoc alias emchat-world))))
+ (if (eq tag 'all)
+ plist
+ (getf plist tag))))
+
+(defun emchat-world-putf (alias tag value)
+ "For ALIAS put property of TAG with VALUE."
+ (let* ((buddy (assoc alias emchat-world))
+ (plist (cddr buddy)))
+ (if buddy (setcdr (cdr buddy) (putf plist tag value)))))
+
+(defun emchat-alias-uin (alias)
+ "Return an uin from an ALIAS in `emchat-world'.
+Return uin if ALIAS is already an uin.
+Return 0 if no corresponding uin or invalid uin.
+If called interactively, display and push uin into `kill-ring'."
+ (interactive (emchat-completing-aliases "UIN from alias: " 'single))
+ (let ((uin (second (assoc alias emchat-world))))
+ (unless uin
+ (when (emchat-valid-uin-p alias)
+ (setq uin alias)))
+ (when (interactive-p)
+ (message uin)
+ (kill-new uin))
+ uin))
+
+(defun emchat-uin-alias (uin)
+ "Return an alias from an UIN in `emchat-world'.
+Return UIN if no corresponding ALIAS.
+If called interactively, display and push alias into `kill-ring'."
+ (interactive (list (read-string "alias from uin: ")))
+ (let ((alias (or (first (find uin emchat-world :key 'second :test 'string=))
+ ;; not found, return uin
+ uin)))
+ (when (interactive-p)
+ (message alias)
+ (kill-new alias))
+ alias))
+
+;;;###autoload
+(defun emchat-world-update ()
+ "Read `emchat-world-rc-filename' and update various user variables.
+Need to call this whenever RC is modified and to be updated.
+RC file is not closed if it is the buffer of current window or it is modified."
+ (interactive)
+ (save-excursion
+ (let (no-killing-at-last)
+ (setq emchat-world nil)
+ (set-buffer (find-file-noselect emchat-world-rc-filename))
+ ;; don't kill if rc file is buffer in current window
+ (setq no-killing-at-last
+ (or (buffer-modified-p)
+ (eq (window-buffer) (current-buffer))))
+ (goto-char (point-min))
+ (while (search-forward-regexp emchat-world-rc-regexp nil t)
+ (let* ((uin (match-string 1))
+ (alias (replace-regexp-in-string
+ emchat-world-ssi-id-regexp ""
+ (match-string 2)))
+ (group (replace-regexp-in-string
+ emchat-world-ssi-id-regexp ""
+ (or (match-string 3) "")))
+ buddy)
+
+ ;; idea from Erik Arneson <erik@starseed.com>
+ (set-extent-properties
+ ;; We may consider moving to emchat-uin-alias or somewhere else, if
+ ;; we don't want to waste enourmous unused extents.
+ (make-extent 0 (length alias) alias)
+ `(highlight t duplicable t start-open t keymap ,emchat-alias-map))
+
+ (setq buddy (list alias uin 'rc-index (point)))
+
+ ;; group stuff not used yet
+ (if group
+ (setq buddy
+ (append buddy (read (format "(group (%s))" group)))))
+ (push buddy emchat-world)))
+ (setq emchat-world (nreverse emchat-world))
+ (unless no-killing-at-last
+ (kill-buffer (current-buffer)))))
+
+ (setq emchat-all-aliases (mapcar 'first emchat-world))
+ (setq emchat-all-uin (mapcar 'second emchat-world))
+ ;; Add history files to emchat-world if enabled
+ (when emchat-history-enabled-flag
+ (mapcar
+ #'(lambda (alias)
+ (emchat-world-putf alias 'history
+ (expand-file-name alias emchat-history-directory)))
+ emchat-all-aliases)))
+
+(defun emchat-world-info (alias)
+ "Return local info of buddy ALIAS."
+ ;; TODO
+ (assoc alias emchat-world))
+
+;;; FIXME: Putting the rc file into `outline-minor-mode' is throwing a
+;;; "keymapp nil" error.
+(defun world-mode ()
+ "emchat resource file mode.
+Quick hack for font-lock. Each record is separated by \"==== \" at the
+beginning of the line."
+ (interactive)
+ (kill-all-local-variables)
+ (setq mode-name "world")
+ (setq major-mode 'world-mode)
+ (setq fill-column 100)
+ (auto-fill-mode 1)
+ ;; hiding details for privacy
+ ;(outline-minor-mode)
+ ;(set (make-local-variable 'outline-regexp)
+ ; "==== ")
+ (setq font-lock-keywords
+ ;; highlight separator
+ '(("^==== " 0 font-lock-warning-face t)
+ ;; highlight keyword prefixed with :
+ (":\\(\\w\\|-\\)+" 0 font-lock-reference-face t)))
+ (font-lock-mode 1))
+
+(defun world-sort ()
+ (interactive)
+ (beginning-of-buffer)
+ (sort-subr nil 'world-next-friend 'world-end-friend))
+
+(defun world-next-friend ()
+ (interactive)
+ (let ((result (search-forward "====" nil t)))
+ ;; go back before ====
+ (if result (backward-char 4)
+ ;; required by sort-subr
+ (end-of-buffer))))
+
+(defun world-end-friend ()
+ (interactive)
+ ;; skip current friend
+ (forward-char 1)
+ (let ((result (search-forward "====" nil t)))
+ ;; go back before ====
+ (if result (backward-char 5)
+ (end-of-buffer))))
+
+(defun world-find (alias)
+ "Goto a friend record of ALIAS in `emchat-world-rc-filename'.
+Prefix argument means do not use (load) emchat completing alias feature."
+ (interactive
+ (if current-prefix-arg
+ (list (read-string "find: "))
+ (progn
+ (require 'emchat)
+ (emchat-completing-aliases "find: " 'single))))
+ (find-file emchat-world-rc-filename)
+ (goto-char (point-min))
+ (re-search-forward
+ (concat "^:icq.*?"
+ (regexp-quote alias)
+ "\\b.*$")))
+
+(provide 'emchat-world)
+
+;;; emchat-world.el ends here
--- /dev/null
+;; emchat-xwem.el --- Activity indicator for XWEM tray
+
+;; Copyright (C) 2005 - 2007 Steve Youngs
+
+;; Author: Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created: <2005-10-15>
+;; Homepage: http://www.emchat.org/
+;; Keywords: emchat, icq, xwem, dock, tray
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+;; Puts a spiffy activity indicator into the XWEM systray.
+;; To use this, add...
+;;
+;; (require 'emchat-xwem)
+;; (add-hook 'xwem-after-init-hook 'emchat-xwem-init)
+;;
+;; ...to your ~/.xwem/xwemrc.el
+;;
+
+;;; Todo:
+;;
+;; o Add more XWEM things... can't think of any right now.
+;;
+
+;;; Code:
+(require 'font) ;; for font-x-registry-and-encoding-regexp
+
+(eval-when-compile
+ (autoload 'xwem-dpy "xwem-struct" nil nil 'macro)
+ (autoload 'xwem-message "xwem-misc")
+ (autoload 'xwem-misc-find-cl-by-emacs-frame "xwem-misc")
+ (autoload 'xwem-osd-clear "xwem-osd")
+ (autoload 'xwem-osd-create "xwem-osd")
+ (autoload 'xwem-osd-create-dock "xwem-osd")
+ (autoload 'xwem-osd-destroy "xwem-osd")
+ (autoload 'xwem-osd-destroy-instances "xwem-osd")
+ (autoload 'xwem-osd-get-prop "xwem-osd")
+ (autoload 'xwem-osd-hide "xwem-osd")
+ (autoload 'xwem-osd-icon-data-add "xwem-osd")
+ (autoload 'xwem-osd-p "xwem-osd")
+ (autoload 'xwem-osd-put-prop "xwem-osd")
+ (autoload 'xwem-osd-rem-prop "xwem-osd")
+ (autoload 'xwem-osd-set-color "xwem-osd")
+ (autoload 'xwem-osd-set-font "xwem-osd")
+ (autoload 'xwem-osd-show "xwem-osd")
+ (autoload 'xwem-osd-text "xwem-osd")
+ (autoload 'xwem-osd-text-add "xwem-osd")
+ (autoload 'xwem-popup-menu "xwem-mouse")
+ (autoload 'xwem-select-client "xwem-clients")
+ (defvar xwem-current-cl)
+ )
+
+(defgroup emchat-xwem nil
+ "Group to customize emchat's xwem capabilities."
+ :group 'emchat
+ :prefix "emchat-xwem-")
+
+(defcustom emchat-xwem-osd-enable t
+ "*Non-nil to show incoming messages in OSD."
+ :group 'emchat-xwem
+ :type 'boolean)
+
+(defcustom emchat-xwem-dock-enable t
+ "*Non-nil to start emchat dock in system tray."
+ :group 'emchat-xwem
+ :type 'boolean)
+
+(defcustom emchat-xwem-osd-show-icon t
+ "*Non-nil to show ICQ icon in OSD as well as message."
+ :group 'emchat-xwem
+ :type 'boolean)
+
+(defcustom emchat-xwem-osd-font
+ (font-create-name (make-font :weight "bold" :size 32))
+ "Font to be used to display OSD message."
+ :group 'emchat-xwem
+ :type '(restricted-sexp :match-alternatives (nil try-font-name)))
+
+(defcustom emchat-xwem-osd-color "magenta3"
+ "*Default color for OSD messages."
+ :group 'emchat-xwem
+ :type 'color)
+
+(defcustom emchat-xwem-osd-group-colors
+ '((:girls . "deeppink")
+ (:vip . "gold")
+ (:work . "red3")
+ (:friends . "green3"))
+ "*Alist of colors to be used in OSD for emchat groups.
+Each element is cons in form (GROUP . COLOR)."
+ :group 'emchat-xwem
+ :type '(repeat (cons (keyword :tag "group") color)))
+
+(defcustom emchat-xwem-osd-coordinates '(100 . 700)
+ "*Place on screen for OSD messages."
+ :group 'emchat-xwem
+ :type '(cons (number :tag "X") (number :tag "Y")))
+
+(defcustom emchat-xwem-osd-display-time 3
+ "*Time the OSD to be shown."
+ :group 'emchat-xwem
+ :type 'number)
+
+;;; Internal variables
+
+(defvar emchat-xwem-osd-icon
+ (concat "/* XPM */\n"
+"static char *icq[] = {\n"
+"/* columns rows colors chars-per-pixel */\n"
+"\"50 50 8 1\",\n"
+"\" c #09090C\",\n"
+"\". c #385930\",\n"
+"\"X c #43FD32\",\n"
+"\"o c #33C326\",\n"
+"\"O c #ECE345\",\n"
+"\"+ c #C5C6C7\",\n"
+"\"@ c None\",\n"
+"\"# c #DC3129\",\n"
+"/* pixels */\n"
+"\"@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.+.++@@@@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@@@@++++++@@@@@@++. .+@@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@@@+ .+@@@@+. +@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@@+ .+@@++ .... .+@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@+ .. +@. oXXXXXo. +@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@+ oXXo .+ oXXXXXXXo +@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@+ .XXXXo XXXXXXXXXo .+@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@. oXXXXX. oXXXXXXXXXo .+@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@. oXXXXXX ooXXXXXXXXX +@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@+ oXXXXXX. oXXXXXXXXXo .+@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@+ XXXXXXo .XXXXXXXXX. .@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@+ .XXXXoo oXXXXXXXXX ++++++@@@@@\",\n"
+"\"@@@@@@++...++ oXXXXo .XXXXXXXX .. ..++@@@\",\n"
+"\"@@@+++ . oXXXo .XXXXXXX. . .+@@\",\n"
+"\"@@+. oXXX XXXXXX. .+@\",\n"
+"\"@++ ..... oXX. oXXXXo .ooXo. +@\",\n"
+"\"@+ XXXXXXo .XXo oXXXo XXXXXXXo .+\",\n"
+"\"+. .XXXXXXXXo .oo oXXX .XXXXXXXXo .+\",\n"
+"\"+ XXXXXXXXXXX. . .XX oXXXXXXXXXo .+\",\n"
+"\"+ .XXXXXXXXXXXXo .. oXXXXXXXXXo +@\",\n"
+"\". .XXXXXXXXXXXXXX. .oXXXXXXXXXo .+@\",\n"
+"\". .XXXXXXXXXXXXXX .OOO. .oXXXXXoooo +@@\",\n"
+"\"+ oXXXXXXXXXXXoo OOOOOOO .oo.. .+@@@\",\n"
+"\"+. ooXooooo... .OOOOOOO. .+@@@@\",\n"
+"\"@+. OOOOOOOOO .+@@@\",\n"
+"\"@@+. OOOOOOOOO +@@\",\n"
+"\"@@@++. OOOOOOOO. ..ooooo. +@\",\n"
+"\"@@@@@+ # ### .OOOOOOO. .oXXXXXXXXXXXo. .+\",\n"
+"\"@@@@+. ######## .OOOOO. oXXXXXXXXXXXXXo +\",\n"
+"\"@@@+. ######### .OOO. .XXXXXXXXXXXXXX. +\",\n"
+"\"@@@+ ######### .oXXXoXXXXXXXXo .\",\n"
+"\"@@@+ ######### . . .oXXXXXXXXXXXo .\",\n"
+"\"@@@+ ######## XXo ooXo oXXXXXXXXXXo .\",\n"
+"\"@@@. ###### oXXX oXXX. oXXXXXXXXX. .\",\n"
+"\"@@@+ oXXXX .XXXX. .XXXXXXXo +\",\n"
+"\"@@@@+. oXXXXX. oXXXX .ooXXXo ++\",\n"
+"\"@@@@@++. . ooXXXXX. oXXXXX. .. +@\",\n"
+"\"@@@@@@@+++++ .XXXXXXX. oXXXXXo .+@@\",\n"
+"\"@@@@@@@@@@@. XXXXXXXXo .XXXXXo ... ++@@@\",\n"
+"\"@@@@@@@@@@+ oXXXXXXXX. .XXXXXX. +@++++++@@@@@\",\n"
+"\"@@@@@@@@@@+ .XXXXXXXXXo XXXXXX. .@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@. .XXXXXXXXXo .XXXXX +@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@. .XXXXXXXXXo .XXXo +@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@+ .XXXXXXXXX. .oo. .+@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@+ XXXXXXXXX +. +@@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@+. .oXXXXXo. .@+.. ..@@@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@+ ooXo. +@@@++..++@@@@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@++ +@@@@@@@@@@@@@@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@@@+. .+@@@@@@@@@@@@@@@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@@@@++.....++@@@@@@@@@@@@@@@@@@@@@@@@@@@\"\n"
+"};\n"))
+
+(defvar emchat-xwem-active
+ (concat "/* XPM */\n"
+"static char *noname[] = {\n"
+"/* columns rows colors chars-per-pixel */\n"
+"\"16 16 17 1\",\n"
+"\" c #000100\",\n"
+"\". c #013200\",\n"
+"\"X c #31000b\",\n"
+"\"o c #2c2c00\",\n"
+"\"O c #035500\",\n"
+"\"+ c #037700\",\n"
+"\"@ c #4d0011\",\n"
+"\"# c #736f00\",\n"
+"\"$ c #068600\",\n"
+"\"% c #07ab00\",\n"
+"\"& c #09cb00\",\n"
+"\"* c #08ed00\",\n"
+"\"= c #a00024\",\n"
+"\"- c #d1002f\",\n"
+"\"; c #878200\",\n"
+"\": c #fff82a\",\n"
+"\"> c None\",\n"
+"/* pixels */\n"
+"\">>>> > >>>>\",\n"
+"\">>> + %&. >>>\",\n"
+"\">>> +*$ $**% >>>\",\n"
+"\">>> *& +**$ >\",\n"
+"\"> O* +*% . \",\n"
+"\" O**O O..& .**$ \",\n"
+"\" &***$ oo O**% \",\n"
+"\" O$+O #:: . >\",\n"
+"\"> XX;::oO+++. \",\n"
+"\"> @--@ #o %***& \",\n"
+"\"> ==X $.OO +**& \",\n"
+"\"> $*OO*O O+. \",\n"
+"\">>> O**+.*& >\",\n"
+"\">>> %**+ +& >>>>\",\n"
+"\">>> .&& >>>>>\",\n"
+"\">>>> >>>>>>>\>\"\n"
+"};\n"))
+
+(defvar emchat-xwem-inactive
+ (concat "/* XPM */\n"
+"static char *noname[] = {\n"
+"\"16 16 7 1\",\n"
+"\" c None\",\n"
+"\". c #000100 s foreground\",\n"
+"\"+ c #013200\",\n"
+"\"@ c #2C2C00\",\n"
+"\"# c #000000\",\n"
+"\"$ c #31000B\",\n"
+"\"o c gray s background\",\n"
+"/* pixels */\n"
+"\" ... .... \",\n"
+"\" ..o...oo+. \",\n"
+"\" .ooo.oooo. \",\n"
+"\" ..oo.oooo... \",\n"
+"\" ....oo.ooo..+..\",\n"
+"\".oooo.o++o.oooo.\",\n"
+"\".ooooo.@@.oooo..\",\n"
+"\".oooo.ooo.+.... \",\n"
+"\" ...#$ooo@oooo+.\",\n"
+"\" .ooo#.o@.ooooo.\",\n"
+"\" .oo$oo+oo.oooo.\",\n"
+"\" ....ooo#oo.oo+.\",\n"
+"\" .oooo#oo.... \",\n"
+"\" .oooo.oo. \",\n"
+"\" .+oo.... \",\n"
+"\" .... \"\n"
+"};\n"))
+
+(defvar emchat-xwem-saved-client nil
+ "Saved selected xwem client.")
+
+(defvar emchat-xwem-keymap
+ (let ((map (make-sparse-keymap)))
+ (define-key map [button1] 'emchat-xwem-select-emchat)
+ (define-key map [button3] 'emchat-xwem-restore-client)
+ map)
+ "*Keymap for emchat dock.")
+
+(defvar emchat-xwem-osd nil)
+(defvar emchat-xwem-dock nil)
+
+\f
+(defun emchat-xwem-activity-off ()
+ "Make the EMchat/XWEM activity indicator inactive."
+ (emchat-xwem-dock-change-icon emchat-xwem-inactive)
+ (emchat-xwem-osd-hide))
+
+(defun emchat-xwem-activity-on ()
+ "Make the EMchat/XWEM activity indicator active."
+ (emchat-xwem-dock-change-icon emchat-xwem-active)
+
+ ;; NICK and MESSAGE are set by dynamic binding
+ (declare (special nick message))
+ (emchat-xwem-osd-show-message nick message))
+
+(defun emchat-xwem-init ()
+ "*Display EMchat activity indicator."
+ (interactive)
+
+ ;; Possible create dock
+ (emchat-xwem-dock-change-icon emchat-xwem-inactive)
+
+ (add-hook 'emchat-track-activity-hook 'emchat-xwem-activity-on)
+ (add-hook 'emchat-track-clear-hook 'emchat-xwem-activity-off))
+
+(defun emchat-xwem-fini ()
+ "Remove the EMchat activity indicator from the XWEM systray."
+ (interactive)
+
+ (emchat-xwem-dock-destroy)
+ (emchat-xwem-osd-destroy)
+
+ (remove-hook 'emchat-track-activity-hook 'emchat-xwem-activity-on)
+ (remove-hook 'emchat-track-clear-hook 'emchat-xwem-activity-off))
+
+\f
+;; OSD
+(defun emchat-xwem-osd-create ()
+ "Create OSD for emchat messages."
+ (setq emchat-xwem-osd
+ (xwem-osd-create (xwem-dpy) (car emchat-xwem-osd-coordinates)
+ (cdr emchat-xwem-osd-coordinates)
+ 2048 1024))
+ (xwem-osd-set-font emchat-xwem-osd emchat-xwem-osd-font))
+
+(defun emchat-xwem-osd-destroy ()
+ "Destroy emchat OSD."
+ (when emchat-xwem-osd
+ (when (itimerp (xwem-osd-get-prop emchat-xwem-osd 'timer))
+ (delete-itimer (xwem-osd-get-prop emchat-xwem-osd 'timer)))
+ (xwem-osd-destroy emchat-xwem-osd)
+ (setq emchat-xwem-osd nil)))
+
+(defun emchat-xwem-osd-color-for-nick (nick)
+ "Return OSD color to use for NICK."
+ (let ((groups (plist-get (assoc nick emchat-world) 'group)))
+ (or (cdr (find groups emchat-xwem-osd-group-colors
+ :key #'car :test #'(lambda (g i)
+ (member i g))))
+ emchat-xwem-osd-color)))
+
+(defun emchat-xwem-osd-show-message (nick message)
+ "Display NICK and MESSAGE in emchat OSD."
+ (when emchat-xwem-osd-enable
+ (unless emchat-xwem-osd
+ (emchat-xwem-osd-create))
+
+ ;; Find and set proper color
+ (xwem-osd-set-color emchat-xwem-osd (emchat-xwem-osd-color-for-nick nick))
+
+ ;; Just make sure OSD is clear
+ (xwem-osd-clear emchat-xwem-osd)
+
+ (when emchat-xwem-osd-show-icon
+ (xwem-osd-icon-data-add emchat-xwem-osd emchat-xwem-osd-icon))
+ (xwem-osd-text-add
+ emchat-xwem-osd
+ (if emchat-xwem-osd-show-icon
+ (glyph-width (make-glyph (vector 'xpm :data emchat-xwem-osd-icon)))
+ 0) 0
+ (encode-coding-string
+ (format "%s: %s" nick message)
+ (and (string-match font-x-registry-and-encoding-regexp
+ emchat-xwem-osd-font)
+ (intern (downcase (format "%s-%s"
+ (match-string 1 emchat-xwem-osd-font)
+ (match-string 2 emchat-xwem-osd-font)))))
+ ))
+
+ (xwem-osd-show emchat-xwem-osd)
+
+ (when (itimerp (xwem-osd-get-prop emchat-xwem-osd 'timer))
+ (delete-itimer (xwem-osd-get-prop emchat-xwem-osd 'timer)))
+ (xwem-osd-put-prop emchat-xwem-osd 'timer
+ (start-itimer "emchat-osd" #'emchat-xwem-osd-hide
+ emchat-xwem-osd-display-time))))
+
+(defun emchat-xwem-osd-hide ()
+ "Hide emchat OSD."
+ (when (xwem-osd-p emchat-xwem-osd)
+ (xwem-osd-hide emchat-xwem-osd)
+ (xwem-osd-destroy-instances emchat-xwem-osd)
+ (when (itimerp (xwem-osd-get-prop emchat-xwem-osd 'timer))
+ (delete-itimer (xwem-osd-get-prop emchat-xwem-osd 'timer)))
+ (xwem-osd-rem-prop emchat-xwem-osd 'timer)))
+
+;; Dock
+(defun emchat-xwem-dock-create ()
+ "Create emchat dock."
+ (setq emchat-xwem-dock
+ (xwem-osd-create-dock (xwem-dpy) 16 16
+ (list 'keymap emchat-xwem-keymap)))
+ (xwem-osd-show emchat-xwem-dock))
+
+(defun emchat-xwem-dock-destroy ()
+ "Destroy emchat dock."
+ (when (xwem-osd-p emchat-xwem-dock)
+ (xwem-osd-destroy emchat-xwem-dock))
+ (setq emchat-xwem-dock nil))
+
+(defun emchat-xwem-dock-change-icon (icon)
+ "Change emchat dock icon to ICON."
+ (when emchat-xwem-dock-enable
+ (unless emchat-xwem-dock
+ (emchat-xwem-dock-create))
+ (xwem-osd-icon-data-add emchat-xwem-dock icon)))
+
+\f
+;;; Commands
+
+;; Note: we can use ordinary Emacs commands here, because interactive
+;; form is empty, for complex commands we must use
+;; `define-xwem-command' and `xwem-interactive'.
+
+(defun emchat-xwem-select-emchat ()
+ "Make emchat be current client."
+ (interactive)
+ (let ((eicl (xwem-misc-find-cl-by-emacs-frame emchat-frame)))
+ (setq emchat-xwem-saved-client (xwem-cl-selected))
+ (xwem-select-client eicl)
+ (emchat-show-window)))
+
+(defun emchat-xwem-restore-client ()
+ "Display unseen senders."
+ (interactive)
+ (if (xwem-cl-alive-p emchat-xwem-saved-client)
+ (xwem-select-client emchat-xwem-saved-client)
+ (xwem-message 'warn "EMchat: Saved client dissapeared")))
+
+(provide 'emchat-xwem)
+;;; emchat-xwem.el ends here
+
--- /dev/null
+;;; emchat.el --- IM client for (S)XEmacs
+
+;; Copyright (C) 2000 - 2008 Steve Youngs
+
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created: Aug 08, 1998
+;; Homepage: http://www.emchat.org/
+;; Keywords: comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;; notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;; notice, this list of conditions and the following disclaimer in the
+;; documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;; may be used to endorse or promote products derived from this
+;; software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+;; Clone of Mirabilis ICQ communication client.
+;;
+;; Entry points:
+;; emchat-login
+;; emchat-show-window
+;; emchat-customize
+;;
+;; See README & INSTALL which come with this package
+;;
+;; This project is done without the consent of Mirabilis.
+;;
+
+;;; Code:
+
+(eval-and-compile
+ (require 'emchat-utils)
+ (require 'timezone)
+ (require 'outline)
+ (require 'emchat-doctor))
+
+(eval-when-compile
+ (defvar emchat-add-user-success)
+ (defvar emchat-user-status)
+ (defvar emchat-user-initial-status)
+ (defvar emchat-buddy-buffer)
+ (defvar emchat-buddy-window-width)
+ (defvar emchat-status-buffer)
+ (defvar emchat-status-use-gutter)
+ (defvar emchat-status-window-height)
+ (defvar emchat-wharf-frame)
+ (defvar seq-num-bin)
+ (defvar seq-num)
+ (defvar user-bin)
+ (defvar local-year)
+ (defvar emchat-fix-nick)
+ (defvar emchat-wharf-frame-use-p)
+ (require 'ehelp)
+ (require 'cus-edit)
+ (require 'browse-url)
+ (require 'passwd)
+ (require 'regexp-opt)
+ (require 'toolbar-utils)
+ (autoload 'emchat-wharf-dec-messages "emchat-wharf"))
+
+(autoload 'emchat-status-auto-reply "emchat-status")
+(autoload 'emchat-status-idle-reply "emchat-status")
+(autoload 'emchat-status-name "emchat-status")
+(autoload 'emchat-change-status "emchat-status" nil t)
+(autoload 'emchat-status-show-buffer "emchat-status" nil t)
+(autoload 'emchat-update-tab-in-gutter "emchat-status")
+(autoload 'emchat-status-v8 "emchat-status")
+(autoload 'emchat-buddy-update-status "emchat-status")
+(autoload 'emchat-buddy-selected-in-view "emchat-buddy")
+(autoload 'emchat-buddy-show-buffer "emchat-buddy" nil t)
+(autoload 'emchat-buddy-select-all-in-view "emchat-buddy")
+
+;; Customize Groups.
+
+(defgroup emchat nil
+ "Mirabilis ICQ communication client."
+ :group 'comm)
+
+(defgroup emchat-info nil
+ "Essential account info."
+ :group 'emchat)
+
+(defgroup emchat-option nil
+ "System settings and general preferences."
+ :group 'emchat)
+
+(defgroup emchat-sound nil
+ "Sound preferences."
+ :group 'emchat)
+
+(defgroup emchat-interface nil
+ "Change the look and \"feel\"."
+ :group 'emchat)
+
+;; Customize.
+;;;###autoload
+(defcustom emchat-directory (file-name-as-directory
+ (expand-file-name ".emchat" (user-home-directory)))
+ "*All EMchat support files and directories hang off this."
+ :type 'directory
+ :group 'emchat)
+
+;; Because of the incredibly complex and hairy twisted maze of
+;; inter-connections between the different EMchat libs, these
+;; emchat-history defcustoms are here instead of in
+;; emchat-history.el. --SY.
+(defgroup emchat-history nil
+ "History preferences."
+ :prefix "emchat-history-"
+ :group 'emchat)
+
+(defcustom emchat-history-enabled-flag nil
+ "*Non-nil means keep \"per-user\" histories."
+ :group 'emchat-history
+ :type 'boolean)
+
+(defcustom emchat-history-directory
+ (file-name-as-directory (expand-file-name "history" emchat-directory))
+ "*Directory path for storing \"per-user\" history files."
+ :type 'directory
+ :group 'emchat-history)
+
+(defcustom emchat-history-mode-hook nil
+ "*Hooks run in `emchat-history-mode'."
+ :type 'hook
+ :group 'emchat-history)
+
+;; This is here and not at the top because some of these libs use
+;; emchat-directory
+(eval-and-compile
+ (require 'emchat-log)
+ (require 'emchat-meta)
+ (require 'emchat-world)
+ (require 'emchat-v8)
+ (require 'emchat-version))
+
+(defcustom emchat-server "login.icq.com"
+ "*Server host to connect to."
+ :type 'string
+ :group 'emchat)
+
+(defcustom emchat-port 5401
+ "*Port to connect to."
+ :type 'number
+ :group 'emchat)
+
+;;;###autoload(autoload 'emchat-prefix "emchat-menu" nil nil 'keymap)
+(defun emchat-install-bindings (&optional sym value)
+ (when (eq (key-binding (symbol-value sym)) emchat-prefix)
+ (global-set-key (symbol-value sym) nil)) ; unbind old
+ (if (key-binding value)
+ (progn
+ (lwarn 'binding 'warning
+ "%S already bound, reseting `emchat-prefix-key'" value)
+ (set sym nil))
+ (global-set-key value emchat-prefix)
+ (set sym value)))
+
+(defcustom emchat-prefix-key [(meta ?`)]
+ "*Default global prefix key for EMchat.
+
+If you change this outside of the customize buffer you _MUST_ use
+`customize-set-variable', not `setq'."
+ :type 'sexp
+ :set 'emchat-install-bindings
+ :initialize 'custom-initialize-default
+ :group 'emchat)
+
+(defcustom emchat-use-sound-flag nil
+ "*Whether to use sound or not."
+ :group 'emchat-sound
+ :type 'boolean
+ :tag "Use Sound")
+
+(defcustom emchat-sound-directory
+ (file-name-as-directory (expand-file-name "sounds" emchat-directory))
+ "*Directory where sound files are kept."
+ :group 'emchat-sound
+ :type 'directory
+ :tag "emchat-sound-directory")
+
+(defcustom emchat-sound-alist
+ '((message-sound . nil)
+ (chat-sound . nil)
+ (url-sound . nil)
+ (buddy-sound . nil)
+ (auth-sound . nil)
+ (emailx-sound . nil)
+ (pager-sound . nil)
+ (system-sound . nil))
+ "*Sound event to sound file alist.
+The possible sound events are:
+ \"message-sound\" - Incoming message sound.
+ \"chat-sound\" - Incoming chat request sound.
+ \"url-sound\" - Incoming url sound.
+ \"buddy-sound\" - Online notify sound.
+ \"auth-sound\" - Authorise sound.
+ \"emailx-sound\" - Email express sound.
+ \"pager-sound\" - Pager sound.
+ \"system-sound\" - System message sound."
+ :group 'emchat-sound
+ :type '(repeat
+ (cons (sexp :tag "Sound Event")
+ (sexp :tag "Sound File")))
+ :tag "Sounds")
+
+(defcustom emchat-coding-system
+ (when (featurep '(or mule file-coding))
+ (if (eq default-buffer-file-coding-system 'cyrillic)
+ (find-coding-system 'windows-1251)
+ default-buffer-file-coding-system))
+ "*Coding for incoming and outgoing messages.
+This feature is supported only in Emacs with MULE
+Nil means not to use any codings.
+See `list-coding-systems'."
+ :group 'emchat-option
+ :type (append '(choice (item nil))
+ (when (fboundp 'coding-system-list)
+ (mapcar
+ #'(lambda (x)
+ (list 'item x))
+ (coding-system-list)))))
+
+(defcustom emchat-auto-response-messages-p t
+ "Set this to non-NIL to send automatic messages.
+The automatic messages are those that are sent when somebody
+sends you a message while you are 'away', 'na', 'dnd', or 'occ'."
+ :tag "Send auto-response messages."
+ :type 'boolean
+ :group 'emchat-option)
+
+(defcustom emchat-auto-reply-away
+ "I am currently away from the computer.
+
+If you would like to be notified when I am back online
+send me a message with \",,notify-me\" in it.
+
+This message has been automatically sent to you
+by the (S)XEmacs IM client \"EMchat\".
+<http://www.emchat.org/>"
+ "Auto reply with this when you are away."
+ :group 'emchat-option)
+
+(defcustom emchat-auto-reply-occ
+ "I am currently occupied.
+
+If you would like to be notified when I am back online
+send me a message with \",,notify-me\" in it.
+
+This message has been automatically sent to you
+by the (S)XEmacs IM client \"EMchat\".
+<http://www.emchat.org/>"
+ "Auto reply with this when you are occupied."
+ :group 'emchat-option)
+
+(defcustom emchat-auto-reply-dnd
+ "Hey, the sign on the door says \"Do Not Disturb\"!
+
+Leave me a message, if you feel you must.
+I might get back to you.
+
+If you would like to be notified when I am back online
+send me a message with \",,notify-me\" in it.
+
+This message has been automatically sent to you
+by the (S)XEmacs IM client \"EMchat\".
+<http://www.emchat.org/>"
+ "Auto reply with this when you want to leave alone."
+ :group 'emchat-option)
+
+(defcustom emchat-auto-reply-na
+ "I am currently not available.
+
+If you would like to be notified when I am back online
+send me a message with \",,notify-me\" in it.
+
+This message has been automatically sent to you
+by the (S)XEmacs IM client \"EMchat\".
+<http://www.emchat.org/>"
+ "Auto reply with this when you are not available."
+ :group 'emchat-option)
+
+;; FIXME: How can I make this display how long we've been away
+(defcustom emchat-idle-reply-away
+ "I must be too busy to talk because I have
+been idle now for at least...seconds
+
+If you would like to be notified when I am back online
+send me a message with \",,notify-me\" in it.
+
+This message has been automatically sent to you
+by the (S)XEmacs IM client \"EMchat\".
+<http://www.emchat.org/>"
+ "Auto reply with this when you have idled away."
+ :group 'emchat-option)
+
+;; FIXME: How can I make this display how long we've been away
+(defcustom emchat-idle-reply-na
+ "I must be too busy to talk because I have
+been idle now for at least...seconds
+
+If you would like to be notified when I am back online
+send me a message with \",,notify-me\" in it.
+
+This message has been automatically sent to you
+by the (S)XEmacs IM client \"EMchat\".
+<http://www.emchat.org/>"
+ "Auto reply with this when you have idled to na."
+ :group 'emchat-option)
+
+(defcustom emchat-auto-response-never-send-to nil
+ "*This is a list of people that shouldn't get auto-responses.
+
+When you add someone's alias here and they send you a message while
+your status would cause an automatic response to be sent, they won't
+be sent one."
+ :type '(repeat (string :tag "Alias"))
+ :group 'emchat-option)
+
+(defcustom emchat-oops-msg-wrong-recipient
+ "That last message was meant for somebody else.
+Sorry about that. :-)"
+ "*The \"apology\" sent when you send to the wrong person."
+ :type 'string
+ :group 'emchat-option)
+
+(defcustom emchat-start-in-new-frame nil
+ "*If non-NIL, EMchat will start in its own frame."
+ :group 'emchat-interface
+ :type 'boolean)
+
+(defcustom emchat-new-message-hook nil
+ "*Hooks to run when there is an incoming message.
+Dynamically ALIAS and MESSAGE are binded to be used in hooks."
+ :group 'emchat-option
+ :type 'hook)
+
+(defcustom emchat-read-message-hook nil
+ "*Hooks run when a message is marked as \"read\"."
+ :group 'emchat-option
+ :type 'hook)
+
+(defcustom emchat-system-message-hook nil
+ "*Hooks run when a \"system\" message is received."
+ :group 'emchat-option
+ :type 'hook)
+
+(defcustom emchat-load-hook nil
+ "*Hooks run after EMchat has loaded everything up."
+ :type 'hook
+ :group 'emchat-option)
+
+(defcustom emchat-missed-message-hook nil
+ "*Hooks run when SRV_MISSED_ICBM packet comes in.
+
+This is usually when you are getting too many incoming messages at
+once. You can use this hook, for example to send back a \"please
+resend\" message to the original sender.
+
+It is called with 3 arguments:
+
+ ALIAS -- The alias/UIN of the person who sent the message that
+ caused the SRV_MISSED_ICBM packet to be sent. \(string\)
+ NUM -- The number of missed messages. \(integer\)
+ REASON -- The reason that the messages were dropped. \(string\)"
+ :type 'hook
+ :group 'emchat-option)
+
+;; Some debugging counters. Do NOT set any of these.
+(defvar emchat-dropped-packet-counter 0
+ "For debug purpose only.")
+
+(defvar emchat-resend-packet-counter 0
+ "For debug purpose only.")
+
+(defvar emchat-recent-packet nil
+ "The most recent incoming packet.
+For debug only.")
+
+(defvar emchat-trimmed-packet-counter 0
+ "For debug purpose only.")
+
+(defvar emchat-error-packets nil
+ "A list of error incoming packets.
+For debug only.")
+
+(defcustom emchat-about-fields
+ '((:nick . "Nick Name")
+ (:first-name . "First Name")
+ (:second-name . "Surname")
+ (:email . "Email")
+ (:country . "Country")
+ (:city . "City")
+ (:state . "State")
+ (:zip . "Postal Code")
+ (:phone . "Phone")
+ (:fax . "Fax")
+ (:cellular . "Cellular")
+ (:flags . "Flags")
+ (:web-indicator . "Web Indicator"))
+ "*Alist of field . field-name for basic info queries."
+ :type '(repeat (cons :tag "Field"
+ (choice :tag "Field Keyword"
+ (const :tag "Nick Name" :value :nick)
+ (const :tag "First Name" :value :first-name)
+ (const :tag "Second Name" :value :second-name)
+ (const :tag "Email" :value :email)
+ (const :tag "Country" :value :country)
+ (const :tag "City" :value :city)
+ (const :tag "State" :value :state)
+ (const :tag "Phone" :value :phone)
+ (const :tag "Fax" :value :fax)
+ (const :tag "Street" :value :street)
+ (const :tag "Cellular" :value :cellular)
+ (const :tag "ZIP Code" :value :zip)
+ (const :tag "Flags" :value :flags)
+ (const :tag "Web Indicator" :value :web-indicator))
+ (string :tag "Field Name")))
+ :group 'emchat)
+
+(defcustom emchat-about-more-fields
+ '((:age . "Age")
+ (:gender . "Gender")
+ (:homepage . "Homepage")
+ (:birth-year . "Birth Year")
+ (:birth-month . "Birth Month")
+ (:birth-day . "Birth Day")
+ (:lang1 . "Language")
+ (:lang2 . "Second Language")
+ (:lang3 . "Third Language")
+ (:ocity . "Old City")
+ (:ostate . "Old State")
+ (:ocountry . "Old Country")
+ (:marital . "Marital Status"))
+ "*Alist of field . fieldname for extended info queries."
+ :type '(repeat (cons :tag "Field"
+ (choice :tag "Field Keyword"
+ (const :tag "Age" :value :age)
+ (const :tag "Gender" :value :gender)
+ (const :tag "Homepage" :value :homepage)
+ (const :tag "Birth Year" :value :birth-year)
+ (const :tag "Birth Month" :value :birth-month)
+ (const :tag "Birth Day" :value :birth-day)
+ (const :tag "Language" :value :lang1)
+ (const :tag "Second Language" :value :lang2)
+ (const :tag "Third Language" :value :lang3)
+ (const :tag "Originate City" :value :ocity)
+ (const :tag "Originate State" :value :ostate)
+ (const :tag "Originate Country" :value :ocountry)
+ (const :tag "Marital" :value :marital))
+ (string :tag "Documentation")))
+ :group 'emchat)
+
+(defcustom emchat-auth-accept-reason "You are AUTHORISED!"
+ "*Default reason for rejecting incoming auth requests."
+ :type 'string
+ :group 'emchat)
+
+(defcustom emchat-auth-reject-reason "Authorisation Rejected!"
+ "*Default reason for rejecting incoming auth requests."
+ :type 'string
+ :group 'emchat)
+
+(defcustom emchat-auth-request-reason "Please add me to your contact list"
+ "*Message to send with outgoing auth requests."
+ :type 'string
+ :group 'emchat)
+
+(defun emchat-init-visible-list (&rest args)
+ "Initialises the default value for `emchat-visible-contacts'."
+ (when (file-readable-p emchat-world-rc-filename)
+ (emchat-world-update)
+ (mapcar
+ #'(lambda (e)
+ (car e))
+ emchat-world)))
+
+(defcustom emchat-visible-contacts (emchat-init-visible-list)
+ "*List of contacts on your \"visible\" list."
+ :type '(repeat (string :tag "Contact Alias Name"))
+ :initialize #'custom-initialize-reset
+ :get #'emchat-init-visible-list
+ :set #'custom-set-default
+ :group 'emchat)
+
+(defcustom emchat-invisible-contacts nil
+ "*List of contacts on your \"invisible\" list."
+ :type '(repeat (string :tag "Contact Alias Name"))
+ :group 'emchat)
+
+;;; Internal variables
+(defcustom emchat-user-password nil
+ "*Password for your ICQ account.
+Nil means prompt for entering password every time you login."
+ :group 'emchat-info)
+
+(defvar emchat-ctx nil
+ "Current emchat context in emchat-v8 protocol.
+Internal variable, do not modify.")
+
+;;;###autoload
+(defun emchat-version (&optional arg)
+ "Return the version of emchat you are currently using.
+If ARG, insert version string at point."
+ (interactive "P")
+ (if arg
+ (insert (message "EMchat: %s" emchat-version))
+ (message "EMchat: %s" emchat-version)))
+
+;;;###autoload
+(defun emchat-copyright ()
+ "*Display the copyright notice for EMchat."
+ (interactive)
+ (with-electric-help
+ '(lambda ()
+ (insert
+ (with-temp-buffer
+ (erase-buffer)
+ (insert-file-contents (locate-library "emchat.el"))
+ (goto-char (point-min))
+ (re-search-forward ";;; Commentary" nil t)
+ (beginning-of-line)
+ (narrow-to-region (point-min) (point))
+ (while (re-search-backward "^;+ ?" nil t)
+ (replace-match "" nil nil))
+ (buffer-string (current-buffer)))))
+ "*EMchat Copyright Notice*"))
+
+(defconst emchat-donation-notice
+ "EMchat is an Open Source project and we have had a lot of fun in
+getting it into your hands. But this project is NOT a \"for profit\"
+organisation. We do not receive any funding, Government grants, or
+subsidies of any kind. None of us who are involved with the project
+are remunerated in any fashion for what we do with EMchat. We are all
+just volunteers, coding in our spare time.
+
+Often the end user doesn't realise that their \"free\" software has
+come at some considerable cost. Costs and expenses like...
+
+ Bandwidth and ISP expenses
+ Hardware updates and maintenance expenses
+ Hosting expenses
+ Domain name registrations
+ Electricity and other utility expenses
+ Outrageous amounts of coffee for all-night coding sessions
+
+If you have found this software useful/cool/entertaining please
+consider dipping into your hard earned and making a donation. Doing
+so will give you the eternal gratitude and thanks from the EMchat
+team, and think of the warm fuzzies you'll get.
+
+Seriously, even if you decide against making a donation at this time,
+I would like to sincerely thank you for at least taking the time to
+consider it. I hope you enjoy EMchat as much as we have enjoyed writing
+it for you.
+
+Steve Youngs
+EMchat Project Lead.
+
+\t\t [Donate]\t\t\t [Cancel]
+
+\t\t"
+ "Contents of donation buffer.")
+
+(defconst emchat-paypal-glyph
+ "iVBORw0KGgoAAAANSUhEUgAAAG4AAAAXCAIAAABlFO2lAAAACXBIWXMAAAsTAAALEwEAmpwY
+AAAAB3RJTUUH1wsQEBYNmimKowAACOlJREFUWMPtmWtwVdUVx3/ncV/n3pubBAIhQF4QkgtJ
+6gMBrVhfUxSstkjHjlZ8jLUdxk5HRztTqzLUdsaCEsfx0arVqY7TUqfWajWlIqPQiGOLYIE8
+CI8QyDtc7vu8z+mHewMhxDGg0w+drDkf9pyz9//813+vtfY+ZwvtnLLapgiTdjbWcW/iZFto
+PylicYK5V1I0H6TxRgngfg7gmEcC8PmdvxDtHGw02ue1J/5eYWLkHVJH6HqL3khOUKE9p2Pd
+NBrXUFyPHJyMtYmarZHp5T/PsLu1496EDBBJUP8g0y/54sHuSMz9f9iXdEcOEqmh4YccvR2Q
+a5siyAmmXoiV/XKZ9ZWk5/+sJnx1gKEKps6sbUrLAFNnYqUR5AmME8H5PwrLr8Id12JKA+yQ
+AQQPRhrJc1oPXx3+RnBJvolrIsiErkUMYHaT/XgExUUYlSGemShfR92Nsf8sJ/ZqpGKsPjLb
+xz7K0wAcnAzGIfSOM5w5ncb4Do/0yTXEAN5qrGGsAQDPLJRL0Haj7z8XKR0XkAFcAzONM0rK
+QKP+YrH6yxZEIh3fEqzXXe/1qQv2OP2Gd2WJ0nQhqQ/HInrLzW3RzO0tgbWVvtUG6t6JUila
+lbrusL2rzXN1UfCli0m+Nw4NwCuKs32+W6b77ioiueXLxaLiJBcYm2T5fK+8UEP0mFtrM3e1
+BNZV+b6vo+47OzTHwtFHpDQz2BnsUQkeDNtt2Vwo2LvS8qIl+hMDTr8BiFEFoxtfA8F6RD+O
+TmY3qU/wh+19GUBqDCEEmHonmc9IbUcIEVmKrxxcsq0ktiEKuWkE8FebWyx7VxqwO1WkWRhp
+IN9nhIb/5xWCIunP9Ki/6MJf7Vs1B+0IBUvxzca1ye4j+U9EgaLr8VWQ3oUyH9cg9hZ2jOCS
+sVSLLrbeD2mPdyqPz6Xgmwz/QaxpUH5TK583jHqU8JV4Z+Vh0y04LlNuOA32xNsYw6dIujZG
+IlcsIJVA7cdKnrrkIrs1IyiSONNn7Uw6/aXab3uleQogRYNIhdrTUxONe+JlHyUWfKa9MJPQ
+hYgRuzUDSPVB/ffF8Rkt6q/ChC539FWZNUZi7s7EvE/VxyIUXoORwErlXxReqq3vFqd75SsK
+naMaVhA7i5XESJykAfhum+G7qV9pmguYfxkiEHXSKzM/0BLV/0pEd6sbiym8hsLlmTsy8dIW
+dUNhIro7uajDHlxB6NKxVIuv0zcVZn/cCWTvPxAv30Hh97R1Q9k1HcK0Gid5TeYu9RRswTKK
+V4yFHViO4D9FUhsg3jYiZQa6m1EH0WPocYw07hT7gCrWKfKisP3vtLq2S74gJNYEACmqoA8K
+paL/gfLAI1VCoayt73bdxXim2/syYoU/FzuBhysDD8uuVZle2e4c0Pz3zZYviegv9JoflSCX
+ocfRY3gqzWbT3pfx/WSWND+Ig31Aw/WiJ9ATGKk8jVKvoGQZbharA4CbtN1sUfrGNuvTlH9t
+pdQY0p/tMbcU4y2z2zKA4BM9N0x1enSzOYkUHktVL5cXeqS5ASRBeW5e8MVaRN1uy4gVfkxn
+orC+SvQ4egJ1kO53iWkjCQ4M7OXEXsKVBEoJzrUP6piuVKdIDUH1kcPYbnjzeZkfdQgFkljq
+OEfnm81DVksPtpvfVHgF1wg7RzREQXvqmPLcPO+lu+hrN7asco7pgPpoV75Gx0zSvQzuQOvj
+0ge1Dd3CFI/nqiLzneO5HJeicYZaAIJzcjTEWoV0G6k+J6kBYpXfeG3Q6TOUDXO83x4SQqXW
+9rh9QJVThU6fIS8p8D9QZL5rGK/0CxHZGSowm3vGUJXqfE7CEiv93hUiHevc9Eanz/Asn3IK
+9vpeITT7DNiI+a6VgyXeysDHAIMtGCO7zFP10YDjXdBFRbV9OJMLQHlhAabrvWW6WON3Dqvy
+wgLsrPpozNoWDzxaJc4JZO9oF2Z4BQas1jAuYqXfOag6B1W+dgwhnEtP5ckascybq7yS8jJ7
+mzBiVN1hvOXYnSqQXLwzX8E7s9TIHNsBUFGVpzFPQe+nZq1+dy/gXVlibj0BSAuCWD35qlKn
+5BryxRHie+zWWbkO6rq+sVSdY26izB0y5YsKSB/ieLudzjtr78/mYR13PNh9J2Hp+iuDLWdu
+rM6wwka7NZsri1Jkc+ChisA9utOh4iBFFRzb6dVzRdf885CrO9KCIPpgbs0J/KxCvqxQazpm
+Da8CSSz3A+aWmNNvWNuOG6+0CjPKMWIIMvWPaRuPiqXe4KvR4KvR4It1gL1fpSA6hoabtIz3
+FqRvHTD/EfOsmOK5ShXnBAD9d336phnGy33SgqDncnILlDRfQfLZ7XlRxqGaPuj0Grn8MD6s
+YMYt+YHR4MRhiX827h4VJPCMuooanLb8nLDnHt/lTwvJ53OIYlRh4G++u0uFiKw/1yNM8+YX
+ItfKT2NUUZ6sEkJSdk2Hq1zmuznpuWGqtTWevf+guTUpLyuj/008UHOn8YbjdGneW0s9dc2e
+4G2eawNCgeR0ZohEx9Aw/jSoru1yY2ZgXVVwg8GWet93h703lpjNx7WN3Z4VU0KvzWK4ecTn
+IIFSuy0tzvAKSmocqrEd4rQD8kVh65Oket9B5p6UUvHdlJwQrG8Q98RpikkAgtsUIZKgpPi0
+Xe5Ff2Ta1bxXl1/1gdk30/gUe3/KkZco+w71G7BS9L1N9Rr2r6dzPQ1PUH4bHyzGVrlsO1aS
+bd8Am4Ynmb4MQSbdyaGn6Xk9D1i+moaN7P81nRvyd5YdQu1h29KxNHCxsmQPc2wTXc/j2kgB
+GpooXY5rMbCZ1ocwjtOwkfLVfLCEzAGu2Ino4f3G8alKfha/QeFCHJ3NFdQ/TvlqPliM1jtR
+2DFf8okYgxHBbYpQkqCsHkGa/NdzTh+ODrE9HI3I+QQPVUxKea5S2iS7R1ZwFQqqJqU8d+t+
+ByJyx72J2mfB0Cg5f1KTc7HUYRKM/PrVI3S8Q2gm4XI8BYjipD4T+IvhYqXRhtj/d5IRSIw6
+2wknKJnJtEXI/kmhJlQih3cx2MmJUWc7J23yxPFsbfSJ438BQx3Q9K+c09sAAAAASUVORK5C
+YII="
+ "A base64 encoded paypal donate button.")
+
+(defconst emchat-maybe-later-glyph
+ "iVBORw0KGgoAAAANSUhEUgAAAG4AAAAXCAIAAABlFO2lAAAACXBIWXMAAAsTAAALEwEAmpwY
+AAAAB3RJTUUH1wsQEBEgkLdAEQAACKJJREFUWMPtmVuMXVUZx39r7X32PpeZc6YznXYudKa1
+lHZ6IdzaEGs0IL6CqPGFGKomQDAaagoYAtUEagwF2phSJQYURZEHCCLIRTAojJSCFux12qlz
+a2emc9ozs+dc9tm3tXw4ZzplOqUzxb40/bIfVr59vv9/rf/51rfXRRxg0pZuyXDRZmNd652T
+bXHgpIj1Dpdez5zlYEwXJUCfAXDKKwGc+cdnRTsHOxXtTO2Z84qZdV6R76P3JQYzFUHFgYqO
+y+Zx+Z3Ur8RMXcy1mVpUpjjIfx7no31d6x0TIOOw8j7mf/7swXoi5y4M+4zDMVNklrDqdgbW
+AebSLRlMh7lXE5ZmiWQg4ggbIrSH9hAWwgYT7aM9CGaMY4FZxSGawbwzEHEwIDxbiIGQADoE
+dV6KTE07c1uXbimYAHNbCQsIcwZxstohYSLrkA3IWnSIHkUXEDWIeoSBKqCyqCI6OLuOMo2R
+RsTRPvoEqoQOP7VSmcg6RB3SQrno3BlCBDKOSIENASqPck9TU57mOYfUDmlYBe+ZACKGX8CI
+zSJeJjFqMVsRNkBkQQKjDmMOgKxDldEu2AgTHaJKaB8RQ5joaCKFLYSBSGO2IDOoEqEgClHj
+KA8RQyYQcbRCu2i3+sdUqS9BJlB5vDxBCQEigUxM0gkgjdmKrEN7BANoH+Ui4sgEaLSLKoFE
+JhAWSLQPimhs1lIqDZgA2icooGYjpZnAbPUez7oP9SHJdF0rUnHtxvNrP1DDvvW1xuS2dpRG
+xpFx0ITjRA5CIBPoEOVj2BAHTaw5eCMqrutM/HihfXsb2ibMQhGZwGxA2KBRBYJhwmGUW6Xe
+fsJ9qC+x6XP2t5pQfcgk5jyMugm6PLqE2aSyc/zfj5ira80vLEBpZISRnsQMT4DArMdIoxWq
+RJhDlwhzs5BChShvQsqgSFQkOmWCS1FRerIxxSnqEXa0/xiAItqVN7+Y8bb2q2EfkB1JdIDV
+jpGsFnZjLsEQwsZqJsoTFZAJzDpUCSGjvVnAuLwGGcduw8ig8sgazAxUKl2AloQOQQ6pT1Ib
+y5MEPQRF4o3YSzBqqnSmR5DFaAzfHS0/MpB85FKM+ZguMolZO4kpkiCwWqq5LAyK/ahj+IWZ
+6qA0OsJ3qILmHdxhwvHJx3emNqY4ARGL9hVF0pCtdvivvOr1yk8MGpclAaMjhYiXNx93Vn4w
+1tLpdLxf3jpCrCX8KDXW1Ok9UyQ2L/xAjDV1lu4dAivaVwSC13LO4h3ja3dFPTaxJjWULH7n
+oLN4h7Nkh7vxCNZCSKICtECYlRCjI0V5AGIkVpQ35ybptowQa/J+e7z0/UNAaUP32IJ/IprU
+UPwTmLFWrJbiLQfHWjrdB/qdy94P3kxg1M9Ch3Cc8jHG9k9kZRH6X6XlOqQJ8pNrbAHRNM6k
+SSijbtdYVWO0x6MP8+5HBfOqGtEQiw6WjI4kIJqs+N1tuMp7eqj8cL/93WbzihSWjPYWEU3l
+x46IlJG4pw2I9hYBLGHd2uRtP+o9NpB4eHHh5o9F0oj/cEG4c9z71aD5pbrY6hqCMvEYoRF1
+u7LJEhnB8RBzHiIumoKpdGvSxqWJqKec3LZEpAxdjgo3756KeUNdtL+IQheixE8WGqtGGduJ
+n5upDspj8G1yZbAnJvWxPYzuoXYhiaZT1loSwD06jbNmbdTtEmhjWdJYlXI39hDp2tevKN7R
+JdKGbLXUUS/4Sy7sdIh0tSeWxCibl6ei3YXww3z4zlj87jaRPqFLjaqvbK7NJB5o107kbT+q
+Rnz/2WPqiAe4D/ZWi3suoDjIiY9JXV2hlh1JdESslViDOmaeTmd0JJUTyoVx66sNhHnv1yOn
+Y2onUkO+cWVNcssihp5n+M+Ueqcf8rTOkU78ic/HZH304UQv9E5XWk9zLt8a7a9MsaR5TZpA
+W7fMl0sSqsc1r0mjtbuxN/zHWOLBRXJxovTtA6LZEpaPO2isSftPDZU398smy75jPk5n1JdC
+Y6xIoXUlPY2lycr8TW5dIlusSjk22rvZv41wjDZ7gjqFMKnpQNruD/47lc6OdA6dDczVaXSE
+CqbBXKEqzth1c8j9mw83UDpyxiGf0XmqtOe0Z4r2lSrjMS4ZSNzfntiQUV0lFEZHEh2pQa9S
+mIPns9pTxooUXpZg3Fxdq8sq/PtY/J42MfoyQaEiX/DWqP9s1r33MJa01jXJtjgQvJlTw374
+zpj/7BFRJyn1EhQQZoU62ld0Nw24P8sFr45PQ+fn1KBfST3/JQe3PB2mEe0vAcbyFLmdBOOf
+ZX0pK8tkYrN8DEtVUmNZkr132V/5nSg9V+mW7Eji7LJvaxYZ0/vFUTHPmvg+DGKmjKtqK1HW
+11N0P4qU1by4YY67sUd7OvXUMiPxon2riN00N/zbWGnD4eCtUfPLcxh+mSgLzknq8O0xb9sR
+b9uRqLts394ylS63Qy4YNVfXhjvH3fWHqJlv32p8ErMeL1uVsiNJ9nVEadY6VNUAEHpLhoxD
+Yz1iltvRtW9QdxXvXs/4HrTCSLLoNpbez6HN9D5J6ze47EdELrn3aL6Ro88RFiLnm/4Lx71f
+Dtb8cYXZ8gSHf46RYNWjNN/E8Ms0fplwnK6fMvgC1lxWPUrDWoTEPUrvk/T/hsgFsBq4+mnq
+r53sSd9TlAdZfNckXd+THNhELMM1z5BejvJ5+1pgKubQiyzfRPON7LiZ3Htn2WV9yk7eyTGS
+EXpLhkaHlpUI4zweHNiNrPmTs2I3Stt3XhJfN8TeewlyXACmFbndDGTM6gSvaT+/UgJ7vpfZ
++zhCkv0rPX/ArsWuvSCkjBjvn/iCu5BedN6lBA7fV22k5l9QB5f9r0DG7FrvLN0OfpnGKy8e
+5p6L5XtwmDj69TJ0vUJNK7VtxNJIeVGfGZxiaMIC5SwHX2M8A84pdzu1Do2tzFuDGb8o1IxK
+5PFdjBxi9JS7nYs3jv+XG8f/AUQDon1o6NymAAAAAElFTkSuQmCC"
+ "A base64 encoded png \"Maybe Later\" button.")
+
+(defun emchat-make-donation ()
+ "Proceed with making a donation to the EMchat project."
+ (interactive)
+ (browse-url "http://tinyurl.com/2uzel4")
+ (kill-buffer "*emchat-donate*"))
+
+(defun emchat-no-donation ()
+ "Don't make a donation to the EMchat project."
+ (interactive)
+ (kill-buffer "*emchat-donate*"))
+
+(defconst emchat-donation-map
+ (let* ((map (make-sparse-keymap 'emchat-donation-map)))
+ (define-key map [button1] 'emchat-make-donation)
+ (define-key map [button2] 'emchat-make-donation)
+ (define-key map [button3] 'emchat-make-donation)
+ (define-key map [return] 'emchat-make-donation)
+ map)
+ "A keymap for the extents in the EMchat donation buffer.")
+
+(defconst emchat-nodonation-map
+ (let* ((map (make-sparse-keymap 'emchat-nodonation-map)))
+ (define-key map [button1] 'emchat-no-donation)
+ (define-key map [button2] 'emchat-no-donation)
+ (define-key map [button3] 'emchat-no-donation)
+ (define-key map [return] 'emchat-no-donation)
+ map)
+ "A keymap for the extents in the EMchat donation buffer.")
+
+(defun emchat-donation ()
+ "Make a donation to the EMchat project via PayPal."
+ (interactive)
+ (let ((buf (get-buffer-create "*emchat-donate*"))
+ (donate-help "Make a donation to the EMchat team.")
+ (cancel-help
+ "Thank you for considering a donation... maybe another time.")
+ donate-glyph-ext
+ cancel-glyph-ext
+ donate-text-ext
+ cancel-text-ext)
+ (switch-to-buffer buf)
+ (erase-buffer)
+ (insert emchat-donation-notice)
+ (when (and (device-on-window-system-p)
+ (featurep 'png))
+ (setq donate-glyph-ext (make-extent (point-max) (point-max)))
+ (set-extent-begin-glyph
+ donate-glyph-ext
+ (make-glyph
+ (list (vector 'png ':data (with-temp-buffer
+ (insert emchat-paypal-glyph)
+ (base64-decode-region (point-min)
+ (point-max))
+ (buffer-string))))))
+ (insert "\t\t\t")
+ (setq cancel-glyph-ext (make-extent (point-max) (point-max)))
+ (set-extent-begin-glyph
+ cancel-glyph-ext
+ (make-glyph
+ (list (vector 'png ':data (with-temp-buffer
+ (insert emchat-maybe-later-glyph)
+ (base64-decode-region (point-min)
+ (point-max))
+ (buffer-string))))))
+ (set-extent-property donate-glyph-ext 'keymap emchat-donation-map)
+ (set-extent-property donate-glyph-ext 'help-echo donate-help)
+ (set-extent-property donate-glyph-ext 'balloon-help donate-help)
+ (set-extent-property cancel-glyph-ext 'keymap emchat-nodonation-map)
+ (set-extent-property cancel-glyph-ext 'help-echo cancel-help)
+ (set-extent-property cancel-glyph-ext 'balloon-help cancel-help))
+ (goto-char (point-min))
+ (re-search-forward "\\[Donate\\]" nil t)
+ (setq donate-text-ext (make-extent (match-beginning 0) (match-end 0)))
+ (re-search-forward "\\[Cancel\\]" nil t)
+ (setq cancel-text-ext (make-extent (match-beginning 0) (match-end 0)))
+ (set-extent-property donate-text-ext 'face 'bold)
+ (set-extent-property donate-text-ext 'mouse-face 'highlight)
+ (set-extent-property donate-text-ext 'keymap emchat-donation-map)
+ (set-extent-property donate-text-ext 'help-echo donate-help)
+ (set-extent-property donate-text-ext 'balloon-help donate-help)
+ (set-extent-property cancel-text-ext 'face 'bold)
+ (set-extent-property cancel-text-ext 'mouse-face 'highlight)
+ (set-extent-property cancel-text-ext 'keymap emchat-nodonation-map)
+ (set-extent-property cancel-text-ext 'help-echo cancel-help)
+ (set-extent-property cancel-text-ext 'balloon-help cancel-help)
+ (goto-char (point-min))))
+
+;; Load the toolbar
+(add-hook 'emchat-buddy-mode-hook 'emchat-install-buddy-toolbar)
+(add-hook 'emchat-log-mode-hook 'emchat-install-log-toolbar)
+
+;;; Code - utilities:
+
+;;;###autoload
+(defun emchat-customize ()
+ "Interactively customize settings and preferences."
+ (interactive)
+ (customize-group 'emchat))
+
+\f
+;;;###autoload
+(defun emchat-browse-homepage ()
+ "Browse emchat homepage for news and files."
+ (interactive)
+ (browse-url "http://www.emchat.org/"))
+
+(defcustom emchat-encoding-local 'koi8-r
+ "*Local hosts encoding."
+ :type '(choice (item :tag "ASCII" us-ascii)
+ (item :tag "Russian KOI8-R" koi8-r)
+ (item :tag "Russian CP1251" cp1251))
+ :group 'emchat)
+
+(defcustom emchat-encoding-remote 'cp1251
+ "Remote server encoding."
+ :type '(choice (item :tag "ASCII" us-ascii)
+ (item :tag "Russian KOI8-R" koi8-r)
+ (item :tag "Russian CP1251" cp1251))
+ :group 'emchat)
+
+(defconst emchat-encoding-koi8-r
+ (concat
+ "\301\302\327\307\304\305\243\326\332"
+ "\311\312\313\314\315\316\317\320"
+ "\322\323\324\325\306\310\303\336"
+ "\333\335\337\331\330\334\300\321"
+ "\341\342\367\347\344\345\263\366\372"
+ "\351\352\353\354\355\356\357\360"
+ "\362\363\364\365\346\350\343\376"
+ "\373\375\377\371\370\374\340\361"))
+
+(defconst emchat-encoding-cp1251
+ (concat
+ "\340\341\342\343\344\345\270\346\347"
+ "\350\351\352\353\354\355\356\357"
+ "\360\361\362\363\364\365\366\367"
+ "\370\371\372\373\374\375\376\377"
+ "\300\301\302\303\304\305\250\306\307"
+ "\310\311\312\313\314\315\316\317"
+ "\320\321\322\323\324\325\326\327"
+ "\330\331\332\333\334\335\336\337"))
+
+(defun emchat-translate-string (str from-enc to-enc)
+ "Translate STR from koi8 to cp1251."
+ (let ((fe (ecase from-enc
+ (us-ascii nil)
+ (koi8-r emchat-encoding-koi8-r)
+ (cp1251 emchat-encoding-cp1251)))
+ (te (ecase to-enc
+ (us-ascii nil)
+ (koi8-r emchat-encoding-koi8-r)
+ (cp1251 emchat-encoding-cp1251)))
+ (tt (make-vector 256 nil)))
+ (dotimes (idx (min (length fe) (length te)))
+ (aset tt (char-to-int (aref fe idx))
+ (char-to-string (aref te idx))))
+ (mapconcat #'(lambda (chr)
+ (or (aref tt (char-to-int chr))
+ (char-to-string chr)))
+ str nil)))
+
+(defun emchat-encode-string (string)
+ "Return a encoded string from STRING with DOS stuff added.
+Encode string with `emchat-coding-system'."
+ ;; add DOS stuff
+ ;; "0d" instead to avoid use of ^M
+ ;; which messes up with outline mode
+ (let ((estr (replace-in-string string "\x0a" "\x0d\x0a")))
+ (if (fboundp 'encode-coding-string)
+ (encode-coding-string estr emchat-coding-system)
+ (emchat-translate-string estr emchat-encoding-local emchat-encoding-remote))))
+
+(defun emchat-decode-string (string)
+ "Return a decoded string from STRING with DOS stuff removed.
+It also quote character % to make `format' happy in `emchat-log'.
+Decode string with `emchat-coding-system'."
+ ;; remove DOS stuff
+ ;; "0d0a" instead to avoid use of ^M
+ ;; which messes up with outline mode
+ (let ((dstr (replace-in-string string "\x0d\x0a" "\x0a")))
+ (if (fboundp 'decode-coding-string)
+ (decode-coding-string dstr emchat-coding-system)
+ (emchat-translate-string dstr emchat-encoding-remote emchat-encoding-local))))
+
+(defconst emchat-message-max-size 500
+ "Maximum size of message that ICQ will accept.
+Set it to small because size expands after `emchat-encode-string'.")
+
+(defun emchat-splitter (x)
+ "Split a long message X into parts of maximum length `emchat-message-max-size'.
+Only split at whitespace."
+ (loop
+ with i = emchat-message-max-size
+ while (> (length x) i)
+ do (while (and (not (memq (aref x (incf i -1)) '(? ?\t)))
+ ;; at least half, to safe guard
+ (> i (/ emchat-message-max-size 2))))
+ collect (substring x 0 i) into parts
+ do (setq x (substring x i))
+ finally return (nconc parts (list x))))
+
+(defvar emchat-outgoing-queue nil
+ "Lists of outgoing queue to be sent.
+Each queue consists of the binary string and the resend counter.")
+
+(defvar emchat-frame nil
+ "The frame where EMchat is displayed.")
+
+(defun emchat-connected-p (ctx)
+ "Return non-nil when EMchat is connected to the ICQ server."
+ (memq ctx emchat-v8-connections))
+
+(defun emchat-exit ()
+ "Log out of ICQ and close all EMchat buffers."
+ (interactive)
+
+ (emchat-logout)
+ (set-buffer emchat-log-buffer)
+ (save-buffer)
+ (if emchat-save-log-on-exit-p
+ (rename-file emchat-log-filename
+ (concat emchat-log-filename
+ (format-time-string "-%Y-%b%d-%H%M-%S")))
+ (delete-file emchat-log-filename))
+ (loop for each in '(emchat-log-buffer
+ emchat-buddy-buffer
+ emchat-status-buffer)
+ do (when (buffer-live-p (symbol-value each))
+ (kill-buffer (symbol-value each))))
+ (delete-other-windows)
+ (when (and emchat-start-in-new-frame
+ (frame-live-p emchat-frame))
+ (delete-frame emchat-frame))
+ (setq emchat-frame nil)
+ (when (and (featurep 'emchat-wharf)
+ (frame-live-p emchat-wharf-frame))
+ (delete-frame emchat-wharf-frame))
+ (setq emchat-wharf-frame nil))
+
+(defvar emchat-trimmed-packet nil
+ "*Last incomplete packet.
+Due to limited buffer size of Emacs network buffer, packets can be trimmed
+and attached at the beginning of next callback. Use this in
+`emchat-network-separator' to concatenate a packet across two callbacks.
+Usually only one per 1000 packets needs this.")
+
+;;; Code - client to server packets:
+
+(defvar emchat-current-seq-num 1
+ "Current sequence number in packet.")
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-pack-register-new-user (password)
+; "Pack register new user packet 03fc."
+; (emchat-pack
+; "\xfc\x03"
+; (emchat-int-bin (length password))
+; password
+; "\xa0\x00\x00\x00"
+; "\x24\x61\x00\x00"
+; "\x00\x00\x00\x00"))
+
+;;; FIXME: This needs to be updated for v8
+; (defvar emchat-random-groups
+; '(("general" . "\x01\x00\x00\x00")
+; ("romance" . "\x02\x00\x00\x00")
+; ("games" . "\x03\x00\x00\x00")
+; ("students" . "\x04\x00\x00\x00")
+; ("age-20" . "\x06\x00\x00\x00")
+; ("age-30" . "\x07\x00\x00\x00")
+; ("age-40" . "\x08\x00\x00\x00")
+; ("age-50+" . "\x09\x00\x00\x00")
+; ("women-wanted" . "\x0a\x00\x00\x00")
+; ("man-wanted" . "\x0b\x00\x00\x00"))
+; "Random user groups.")
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-pack-set-random-group (group)
+; "Pack set random group 0564."
+; (emchat-pack
+; "\x64\x05"
+; (cdr (assoc group emchat-random-groups))))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-pack-search-random-user (group)
+; "Pack search random user 056e."
+; (emchat-pack
+; "\x6e\x05"
+; (cdr (assoc group emchat-random-groups))))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-pack-request-authorization ()
+; "Pack request authorization packet 0456."
+; (emchat-pack "\x56\x04"))
+
+;;; Code - server to client packets:
+
+;;; FIXME: Do we have an unknown packet handler for v8?
+; (defun emchat-do-unknown (packet)
+; "Handle any unknown PACKET."
+; (push (cons 'unknown-command emchat-recent-packet)
+; emchat-error-packets)
+; (emchat-log-error
+; "Unknown command: %s"
+; (emchat-bin-hex (substring packet 7 9))))
+
+;;; FIXME: How is this handled now?
+; (defun emchat-do-wrong-password (packet)
+; ;; not authorized?
+; "Handle server command 0064 in PACKET."
+; (emchat-log-error "Your password is invalid"))
+
+(defun emchat-do-forced-logoff (ectx)
+ "Called when another user with same UIN is logged in."
+ (emchat-log-error "Another user with same UIN is logged in!")
+ (emchat-logout))
+
+;; Automatically reconnect when connection unexpectadly closes.
+;; WARNING!! This can cause problems, we should have maximum
+;; reconnections and reconnection rate custom variables.
+(defvar emchat-is-auto-reconnecting nil
+ "Internal variable. Do not set.")
+
+(defun emchat-do-disconnect (ectx)
+ "Handle disconnect from server."
+ (emchat-log-error "Unexpected disconnection from server")
+ (emchat-logout)
+ (if emchat-user-password
+ (progn
+ (setq emchat-is-auto-reconnecting t)
+ (emchat-log-system "Attempting auto-reconnect...")
+ (emchat-login))
+ (with-current-buffer emchat-log-buffer
+ (emchat-log-system
+ (substitute-command-keys
+ "Connection lost, use `\\[emchat-login]' to log back in.")))))
+
+;;; FIXME: How is this handled now?
+; (defun emchat-do-already-logged-in (packet)
+; "Handle server command 00fa PACKET."
+; (emchat-log-error "You are already logged in."))
+
+(defun emchat-do-instant-message (ectx &rest ih-arguments)
+ "Handle incoming instant message."
+ (emchat-do-message-helper
+ (emchat-get-arg :uin) (emchat-get-arg :msg) (emchat-get-arg :msg-type)))
+
+(defun emchat-do-missed-message (ectx &rest ih-arguments)
+ "Handle incoming notice about missed messages."
+ (let ((alias (emchat-uin-alias (emchat-stringular-uin (emchat-get-arg :uin))))
+ (num (emchat-get-arg :missed-messages))
+ (reason (emchat-get-arg :reason)))
+ (emchat-do-message-helper
+ alias
+ (format "Server dropped the last %d message%sfrom: %s
+Reason: %s"
+ num (if (> num 1) "s " " ") alias reason) 'missed)
+ (run-hook-with-args 'emchat-missed-message-hook alias num reason)))
+
+(defun emchat-do-offline-message (ectx &rest ih-arguments)
+ "Handle incoming offline message."
+ (let* ((time-stamp (emchat-get-arg :time-stamp))
+ (year (nth 0 time-stamp))
+ (month (nth 1 time-stamp))
+ (day (nth 2 time-stamp))
+ (hour (1- (nth 3 time-stamp)))
+ (min (nth 4 time-stamp))
+ (monthname (aref emchat-monthnames month))
+ (local-time
+ (timezone-fix-time
+ (format "%s %s %s:%s %s"
+ monthname day hour min year)
+ nil nil))
+ (local-year (aref local-time 0))
+ (local-monthname (aref emchat-monthnames
+ (aref local-time 1)))
+ (local-day (aref local-time 2))
+ (local-hour (aref local-time 3))
+ (local-min (aref local-time 4)))
+
+ (emchat-do-message-helper
+ (emchat-get-arg :uin)
+ (format "(%s %02s) %02s:%02s\n%s"
+ local-monthname local-day local-hour local-min
+ (emchat-get-arg :msg))
+ (emchat-get-arg :msg-type))))
+
+(defun emchat-do-added-you (ectx &rest ih-arguments)
+ "Handle incoming SVR_ADDEDYOU packets."
+ (let ((file emchat-recently-added-by-filename)
+ (uin (emchat-stringular-uin (emchat-get-arg :uin)))
+ (msg (emchat-get-arg :msg))
+ (type (emchat-get-arg :msg-type)))
+ (emchat-do-message-helper uin msg type)
+ (when (or (not (member uin emchat-all-uin))
+ emchat-world-track-all-adds)
+ (with-current-buffer (find-file-noselect file)
+ (unless (search-forward uin nil t)
+ (goto-char (point-max))
+ (insert uin)
+ (save-buffer))
+ (kill-buffer nil))
+ (add-to-list 'emchat-world-recently-added-by
+ (emchat-numeric-uin uin) 'append))))
+
+(defun emchat-do-auth-request (ectx &rest ih-arguments)
+ "Handle incoming SRV_AUTHREQ."
+ (emchat-do-message-helper
+ (emchat-get-arg :uin) (emchat-get-arg :msg) (emchat-get-arg :msg-type)))
+
+(defun emchat-do-auth-accept (ectx &rest ih-arguments)
+ "Handle incoming SRV_AUTHREPLY (accepted)."
+ (emchat-do-message-helper
+ (emchat-get-arg :uin) (emchat-get-arg :msg) (emchat-get-arg :msg-type)))
+
+(defun emchat-do-auth-reject (ectx &rest ih-arguments)
+ "Handle incoming SRV_AUTHREPLY (rejected)."
+ (emchat-do-message-helper
+ (emchat-get-arg :uin) (emchat-get-arg :msg) (emchat-get-arg :msg-type)))
+
+(defun emchat-do-srv-contact-err (ectx &rest ih-arguments)
+ "Handle incoming SRV_CONTACTERR."
+ (emchat-log-error "Contacts Error: %s" (emchat-get-arg :reason)))
+
+(defun emchat-do-srv-general-err (ectx &rest ih-arguments)
+ "Handle incoming SRV_GEN_ERR."
+ (emchat-log-error "Server Error: %s" (emchat-get-arg :reason)))
+
+(defvar emchat-auto-reply-p nil
+ "If non-nil EMchat will not automatically set your state to online.
+
+It is used in `emchat-do-message-helper' and `emchat-send-message-helper'.")
+
+(defvar emchat-user-auto-away-p nil
+ "This variable is set when the auto-away timer expires,
+and it is reset in emchat-send-message-helper and emchat-change-status.")
+
+(eval-when-compile (load "sound"))
+
+(when (featurep 'sxemacs)
+ (defvar emchat-audio-device default-audio-device
+ "The audio device to play sounds on.")
+ (defvar emchat-media-driver nil
+ "Optional driver to use with `emchat-load-media-streams'.
+See `make-media-stream' for what can be used here."))
+
+(defun emchat-load-media-streams (&optional force)
+ "Loads configured sounds into SXEmacs media streams.
+
+With optional prefix arg, FORCE, make the streams even if they already
+exist. This is useful when you want to replace existing sounds."
+ (interactive "p")
+ (emchat-do-in-sxemacs
+ (let ((sound-lst emchat-sound-alist)
+ (stub "emchat::"))
+ (mapcar
+ #'(lambda (el)
+ (when (stringp (cdr el))
+ (let* ((file (expand-file-name (cdr el) emchat-sound-directory))
+ (streamsym (intern (concat stub (symbol-name (car el)))))
+ (stream (ignore-errors (symbol-value streamsym))))
+ (when (and (file-readable-p file)
+ (or force
+ (not (media-stream-p stream))))
+ (set streamsym (make-media-stream :file file emchat-media-driver))))))
+ sound-lst))))
+
+(defun emchat-play-sound-maybe (type)
+ "Play sound TYPE if it exists."
+ (when emchat-use-sound-flag
+ (emchat-do-in-xemacs
+ (when (cdr (assq type emchat-sound-alist))
+ (let ((file (expand-file-name (cdr (assq type emchat-sound-alist))
+ emchat-sound-directory)))
+ (play-sound-file file))))
+ (emchat-do-in-sxemacs
+ (when (media-stream-p
+ (ignore-errors
+ (symbol-value (intern-soft (concat "emchat::" (symbol-name type))))))
+ (let ((stream (symbol-value (intern-soft
+ (concat "emchat::" (symbol-name type))))))
+ (play-media-stream stream emchat-audio-device))))))
+
+(defvar emchat-online-notifiers nil
+ "A list of aliases who have requested online notification.")
+
+(defun emchat-do-message-helper (uin message &optional msg-type)
+ "Helper for handling offline and online messages.
+UIN is uin of message sender.
+MSG-TYPE is type of message. Possible type: `emchat-v8-message-types'.
+MESSAGE is message body of any type."
+ (let ((alias (emchat-uin-alias (emchat-stringular-uin uin)))
+ (type msg-type))
+ (add-to-list 'emchat-active-aliases alias)
+
+ ;; Doctor
+ (if (and emchat-doctor-enabled-flag
+ (member alias emchat-doctor-patients))
+ (emchat-doctor message alias)
+ (when (and emchat-doctor-enabled-flag
+ (equal message emchat-doctor-begin-string))
+ (add-to-list 'emchat-doctor-patients alias)
+ (emchat-doctor-reply emchat-doctor-hello-string alias)))
+
+ ;; Notify
+ (cond
+ ((string-match ",,notify-me\\(\\s-\\|$\\)" message)
+ (add-to-list 'emchat-online-notifiers alias)
+ (emchat-v8-send-simple-message
+ emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias))
+ "Online notification request set.
+Send \",,cancel-notify\" to cancel.")
+ (emchat-log-system (format "Online notify requested by: %s" alias))
+ (emchat-play-sound-maybe 'system-sound))
+ ((string-match ",,cancel-notify\\(\\s-\\|$\\)" message)
+ (setq emchat-online-notifiers (remove alias emchat-online-notifiers))
+ (emchat-v8-send-simple-message
+ emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias))
+ "Online notification request cancelled.")
+ (emchat-log-system (format "Online notify cancellation: %s" alias))
+ (emchat-play-sound-maybe 'system-sound)))
+
+ ;; Auto-response
+ (when (and emchat-auto-response-messages-p
+ (member emchat-user-status
+ '("away" "na" "dnd" "occ")))
+ (if emchat-user-auto-away-p
+ (progn
+ (setq emchat-auto-reply-p t)
+ (emchat-idle-reply-maybe alias))
+ (emchat-auto-reply-maybe alias)))
+
+ (run-hooks 'emchat-new-message-hook)
+
+ (case type
+ (normal
+ (emchat-log-buddy-message
+ alias "%s" (emchat-decode-string message))
+ (emchat-play-sound-maybe 'message-sound))
+ (chat-request
+ (emchat-log-buddy-message
+ alias "Request chat")
+ (emchat-play-sound-maybe 'chat-sound))
+ (url
+ (multiple-value-bind (message url)
+ (values-list (split-string message "\xfe"))
+ (emchat-log-buddy-url
+ alias (emchat-decode-string message) (emchat-decode-string url))
+ (emchat-play-sound-maybe 'url-sound)))
+ ;; Athorization messages
+ (auth-accept
+ (emchat-log-buddy-message
+ alias "Authorisation Accepted!")
+ (emchat-play-sound-maybe 'auth-sound))
+ (auth-reject
+ (emchat-log-buddy-message
+ alias "Authorisation Rejected!\nReason: %s"
+ (substring (emchat-decode-string message) 0 -1))
+ (emchat-play-sound-maybe 'auth-sound))
+ (auth-request
+ (emchat-log-buddy-message
+ alias "Authorisation Request\nReason: %s"
+ (emchat-decode-string message))
+ (emchat-play-sound-maybe 'auth-sound))
+ ;; Pager messages
+ (web-pager
+ (emchat-log-buddy-message
+ alias "Web Pager = %s"
+ (emchat-decode-string
+ (replace-in-string message "[\xfe]+" "\n")))
+ (emchat-play-sound-maybe 'pager-sound))
+ (email-pager
+ (emchat-log-buddy-message
+ alias "Email Pager = %s"
+ (emchat-decode-string
+ (replace-in-string message "[\xfe]+" "\n")))
+ (emchat-play-sound-maybe 'pager-sound))
+ (email-express
+ (emchat-log-buddy-message
+ alias "Email express = %s"
+ (emchat-decode-string
+ (replace-in-string message "[\xfe]+" "\n")))
+ (emchat-play-sound-maybe 'emailx-sound))
+ (added
+ (emchat-log-system (format "%s %s" alias message))
+ (emchat-play-sound-maybe 'system-sound))
+ (contact-list
+ (emchat-log-buddy-message
+ alias "Contact list = %s"
+ (emchat-decode-string
+ (replace-in-string message "\xfe" "\n"))))
+ (get-away
+ (let ((visible (or (member alias emchat-visible-contacts)
+ (not (member alias emchat-invisible-contacts)))))
+ (emchat-log-system (format "%s requested our away msg (%s)"
+ alias
+ (if visible "sent" "not sent")))
+ (when visible
+ (emchat-send-message-helper
+ emchat-auto-reply-away
+ (list alias) 'automatic "away msg sent"))))
+ (get-occ
+ (let ((visible (or (member alias emchat-visible-contacts)
+ (not (member alias emchat-invisible-contacts)))))
+ (emchat-log-system (format "%s requested our occupied msg (%s)"
+ alias
+ (if visible "sent" "not sent")))
+ (when visible
+ (emchat-send-message-helper
+ emchat-auto-reply-occ
+ (list alias) 'automatic "occ msg sent"))))
+ (get-na
+ (let ((visible (or (member alias emchat-visible-contacts)
+ (not (member alias emchat-invisible-contacts)))))
+ (emchat-log-system (format "%s requested our not available msg (%s)"
+ alias
+ (if visible "sent" "not sent")))
+ (when visible
+ (emchat-send-message-helper
+ emchat-auto-reply-na
+ (list alias) 'automatic "na msg sent"))))
+ (get-dnd
+ (let ((visible (or (member alias emchat-visible-contacts)
+ (not (member alias emchat-invisible-contacts)))))
+ (emchat-log-system (format "%s requested our dnd msg (%s)"
+ alias
+ (if visible "sent" "not sent")))
+ (when visible
+ (emchat-send-message-helper
+ emchat-auto-reply-dnd
+ (list alias) 'automatic "dnd msg sent"))))
+ (get-ffc
+ ;; TODO: send our free-for-chat message
+ )
+ ;; SRV_MISSED_ICBM
+ (missed
+ (emchat-log-system (format "%s" message))
+ (emchat-play-sound-maybe 'system-sound))
+ (automatic
+ (emchat-log-buddy-message
+ alias "-=[Automatic Response]=-\n%s"
+ (emchat-decode-string message))
+ (emchat-play-sound-maybe 'system-sound))
+ (otherwise (push (cons 'unknown-message-types
+ emchat-recent-packet)
+ emchat-error-packets)
+ (emchat-log-error "Unknown message type: %S" msg-type)))))
+
+(defvar emchat-auto-reply-never emchat-auto-response-never-send-to
+ "List of people to never send auto-responses to.")
+
+(defun emchat-auto-reply (alias)
+ "Auto-reply to ALIAS/uin depending on `emchat-user-status'.
+Called by `emchat-do-message-helper'."
+ (let ((message (symbol-value (emchat-status-auto-reply emchat-user-status))))
+ (when message
+ (add-to-list 'emchat-active-aliases alias)
+ (emchat-send-message-helper
+ message (list alias) 'automatic "Auto reply sent"))))
+
+(defun emchat-auto-reply-maybe (alias)
+ "Possibly send an auto-response to ALIAS."
+ (unless (or (member alias emchat-auto-reply-never)
+ (member alias emchat-auto-response-never-send-to)
+ (member alias emchat-invisible-contacts)
+ (not (member alias emchat-visible-contacts)))
+ (emchat-auto-reply alias)
+ (add-to-list 'emchat-auto-reply-never alias)))
+
+(defun emchat-idle-reply (alias)
+ "Auto-reply to ALIAS/uin depending on `emchat-user-status'.
+Called by `emchat-do-message-helper'."
+ (let ((message (symbol-value (emchat-status-idle-reply emchat-user-status))))
+ (when message
+ (add-to-list 'emchat-active-aliases alias)
+ (emchat-send-message-helper
+ message (list alias) 'automatic "Idle reply sent"))))
+
+(defun emchat-idle-reply-maybe (alias)
+ "Possibly send an auto-response to ALIAS."
+ (unless (or (member alias emchat-auto-reply-never)
+ (member alias emchat-auto-response-never-send-to)
+ (member alias emchat-invisible-contacts)
+ (not (member alias emchat-visible-contacts)))
+ (emchat-idle-reply alias)
+ (add-to-list 'emchat-auto-reply-never alias))
+ (setq emchat-auto-reply-p nil))
+
+;;; FIXME: this isn't used, but having IP and port info in emchat-world
+;;; would be nice to have again.
+; (defun emchat-do-online (packet)
+; "Handle server command 006e in PACKET."
+; (let ((alias (emchat-bin-alias packet 21))
+; (status (emchat-status-name (substring packet 38 39)))
+; (ip (emchat-bin-ip packet 25))
+; (port (emchat-bin-uin packet 29))
+; (real-ip (emchat-bin-ip packet 33)))
+; (if (emchat-valid-uin-p alias)
+; (push (cons 'unknown-alias emchat-recent-packet)
+; emchat-error-packets))
+; (emchat-buddy-update-status alias status)
+; (emchat-play-sound-maybe 'buddy-sound)
+; (emchat-world-putf alias 'ip ip)
+; (emchat-world-putf alias 'port port)
+; (emchat-world-putf alias 'real-ip real-ip)))
+
+(defun emchat-do-login-confirm (ectx)
+ "Called when emchat successfully connected to icq server."
+ (emchat-log-debug "Successfully logged in to ICQ server")
+ (emchat-log-system "Connected to %s:%d"
+ (emchat-v8-ctx-host ectx)
+ (emchat-v8-ctx-port ectx))
+ (emchat-change-status emchat-user-initial-status 'no-network)
+ (emchat-keep-alive-start)
+ (emchat-check-contact-list)
+ (emchat-activate-contact-list)
+ (message "Welcome to EMchat...")
+ (if emchat-is-auto-reconnecting
+ (setq emchat-is-auto-reconnecting nil)
+ (emchat-show-window)))
+
+;;; FIXME: What to do with this in v8?
+; (defun emchat-do-system-message (packet) ; TODO
+; "Handle server command 01c2 in PACKET."
+; (run-hooks 'emchat-system-message-hook))
+
+(defun emchat-format-field (field field-var &optional format)
+ "Format FIELD.
+FORMAT specifies format to use for FIELD (default is \"%15s: %s\").
+
+Note: USE THIS FUNCTION VERY CAREFULY."
+ (let ((fi-name (cdr (assq field field-var)))
+ (fi-val (emchat-get-arg field)))
+ ;; NOTE: Do not format empty strings
+ (cond ((null fi-val) nil)
+ ((stringp fi-val)
+ (unless (string= fi-val "")
+ (format (or format "%15s: %s\n") fi-name fi-val)))
+ (t (format (or format "%15s: %S\n") fi-name fi-val)))))
+
+(defun emchat-add-user-ssi (uin nick ssi-grp id)
+ "Send a request to add UIN to your server side contact list.
+
+NICK is the name that will appear in the buddy buffer. It defaults to
+whatever UIN has set their nick name to. It can be overridden, in
+fact, you'll be asked if you want to keep the default or choose another
+nick name.
+
+Argument, SSI-GRP is the server side group ID this contact
+should be added to. EMchat has its own notion of contact groups so
+SSI-GRP will rarely, if ever, be need to be set by hand. A value for
+it is obtained from existing group IDs in world.
+
+Argument, ID, is the server side contact ID for this contact. It is
+simply the highest ID from world incremented by 1.
+
+This might change in the future when EMchat has better SSI handling."
+ (let* ((uin (emchat-stringular-uin uin)))
+ (progn
+ (emchat-v8-snac-cli-ssi-edit-begin emchat-ctx)
+ (emchat-v8-snac-cli-ssi-add emchat-ctx uin ssi-grp id nick)
+ (emchat-v8-snac-cli-ssi-edit-end emchat-ctx))))
+
+(defun emchat-do-about-general (ectx &rest ih-arguments)
+ "Handle incoming general about info."
+ (let* ((uin (emchat-get-arg :uin))
+ (alias (emchat-uin-alias (emchat-stringular-uin uin)))
+ (nick (emchat-get-arg :nick)))
+ ;; Dynamically add a new user to your contact list.
+ (if (and (not (member (emchat-stringular-uin uin) emchat-all-uin))
+ emchat-add-user-p)
+ (let ((ssi-grp (emchat-world-ssi-grp))
+ (id (emchat-world-next-ssi-id)))
+ (setq nick (if (y-or-n-p
+ (format "Default nick is set to: \"%s\", accept: "
+ nick))
+ nick
+ (read-string "New nick name: " nil nil alias)))
+ ;; ensure we have a valid nick name
+ (loop until (string-match "^[^:]" nick)
+ do (setq nick
+ (read-string "Invalid Alias (can't begin with \":\"): "
+ nil nil alias)))
+ ;; load up a hash table to carry new user info over to world
+ (setq emchat-world-new-user-hash (make-hash-table :test #'equal :size 6))
+ (puthash :uin uin emchat-world-new-user-hash)
+ (puthash :nick nick emchat-world-new-user-hash)
+ (puthash :ssi-grp ssi-grp emchat-world-new-user-hash)
+ (puthash :id id emchat-world-new-user-hash)
+ (puthash :egrps
+ (read-string
+ "Add user to group[s] (fmt: :group1 :group2 or RET for none): ")
+ emchat-world-new-user-hash)
+ (emchat-add-user-ssi uin nick ssi-grp id))
+ ;; Not adding new user, output about info
+ (emchat-log-info
+ (emchat-decode-string
+ (concat
+ "GENERAL about result =\n"
+ (format "%15s: %d\n" "UIN" uin)
+ (format "%15s: %s\n" "Local alias" alias)
+ (apply 'concat
+ (mapcar #'(lambda (field)
+ (emchat-format-field (car field) emchat-about-fields))
+ emchat-about-fields))
+ "--- END ---"))))))
+
+(defun emchat-do-about-more (ectx &rest ih-arguments)
+ "Handle incoming more about info."
+ (let* ((uin (emchat-get-arg :uin))
+ (alias (emchat-uin-alias (emchat-stringular-uin uin))))
+ (emchat-log-info
+ (emchat-decode-string
+ (concat
+ "MORE about result =\n"
+ (format "%15s: %d\n" "UIN" uin)
+ (format "%15s: %s\n" "Local alias" alias)
+ (apply 'concat
+ (mapcar #'(lambda (field)
+ (emchat-format-field (car field) emchat-about-more-fields))
+ emchat-about-more-fields))
+ "--- END ---")))))
+
+(defun emchat-do-about-about (ectx &rest ih-arguments)
+ "Handle incoming user notes info."
+ (let* ((uin (emchat-get-arg :uin))
+ (alias (emchat-uin-alias (emchat-stringular-uin uin))))
+ (emchat-log-info
+ (emchat-decode-string
+ (concat
+ "ABOUT about result =\n"
+ (format "%15s: %d\n" "UIN" uin)
+ (format "%15s: %s\n" "Local alias" alias)
+ (emchat-get-arg :about) "\n"
+ "--- END ---")))))
+
+(defun emchat-do-search-found (ecxt &rest ih-arguments)
+ "A user we were looking for is found."
+ (apply 'emchat-do-about-general ecxt ih-arguments))
+
+(defun emchat-do-search-found-last (ecxt &rest ih-arguments)
+ "The last user in the search has been found."
+ (apply 'emchat-do-about-general ecxt ih-arguments)
+
+ (let ((status (if (= (emchat-get-arg :status) 1) 'online 'offline)))
+ (if (zerop (emchat-get-arg :missed))
+ (if emchat-add-user-p
+ (puthash :status status emchat-world-new-user-hash)
+ (emchat-log-info "All search results returned"))
+ (emchat-log-info "Too many seach results"))))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-update-info-confirm (packet)
+; "Handle server command 01e0 in PACKET."
+; (emchat-log-info "Update info succeeded"))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-update-info-fail (packet)
+; "Handle server command 01ea in PACKET."
+; (emchat-log-info "Update info failed"))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-update-authorization-confirm (packet)
+; "Handle server command 01f4 in PACKET."
+; (emchat-log-info "Update authorization succeeded"))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-update-authorization-fail (packet)
+; "Handle server command 01fe in PACKET."
+; (emchat-log-info "Update authorization failed"))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-update-info-ext-confirm (packet)
+; "Handle server command 01c8 in PACKET."
+; (emchat-log-info "Update extended info succeeded"))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-new-account-uin (packet)
+; "Handle server command 0046 in PACKET."
+; (emchat-log-info
+; "New uin: %s"
+; (emchat-bin-uin packet 13)))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-search-random-user-found (packet)
+; "Handle server command 0258 in PACKET."
+; (if (< (length packet) 30)
+; (emchat-log-info "Random user search failed")
+; (emchat-query-info (emchat-bin-uin packet 21))))
+
+;;; Code - alias and uin:
+
+(defvar emchat-alias-history nil
+ "History of aliases in `emchat-completing-aliases'.")
+
+(defvar emchat-alias-list-history nil
+ "History of aliases in `emchat-send-message-helper'.
+For sending messages of any kind to a single alias, it records the same
+thing as `emchat-alias-history' does, while sending to multiple aliases, this
+records a list of aliases instead of one by one. This faciliates
+re-sending to a list of aliases in future version.")
+
+(defvar emchat-connected-aliases nil
+ "Aliases that are in any statuses except 'invisible'.")
+
+(defvar emchat-active-aliases nil
+ "Aliases which we have exchanged messages with.")
+
+(defun emchat-process-alias-input (symbol)
+ "Input alias as selected or from completing.
+SYMBOL is the symbol of variable (`alias') to be processed.
+
+Non-nil SYMBOL means no processing.
+Negative argument (press \\[negative-argument] before this command) means
+taking all selected alias in buddy buffer as input.
+Prefix argument (press \\[universal-argument] before this command) means
+completing-read multi aliases from minibuffer.
+Otherwise, completing-read one alias from minibuffer.
+
+See `emchat-completing-aliases'."
+ (or (symbol-value symbol)
+ (set symbol
+ (if (eq '- current-prefix-arg)
+ (emchat-buddy-selected-in-view)
+ (emchat-completing-aliases "to: " (not current-prefix-arg))))))
+
+;;; Code - system main:
+
+(defvar emchat-blurb
+ "As succinctly as possible, tell us:-\n
+\tWhat happened.
+\tWhat you thought should happen.
+\tAnything else that you think is relevant.\n
+*** Please delete these instructions before submitting the report. ***
+======================================================================\n"
+ "Preamble to the bug report.")
+
+;;;###autoload
+(defun emchat-login ()
+ "Login to ICQ server.
+Make connection to server and network if necessary."
+ (interactive)
+ (let* ((uin (progn
+ (emchat-world-update)
+ (emchat-numeric-uin (emchat-alias-uin emchat-user-alias))))
+ (password (or emchat-user-password
+ (read-passwd (format "Password for %s (%d): "
+ emchat-user-alias uin)))))
+
+ (when (equal emchat-user-status "offline")
+ (or (emchat-valid-uin-p uin)
+ (error "Invalid user uin"))
+
+ (setq emchat-trimmed-packet nil) ; hack
+ (setq emchat-current-seq-num 0)
+ (emchat-log-show-buffer nil 'no-select)
+
+ ;; Create emchat v8 context
+ (setq emchat-ctx (emchat-v8-create-ctx uin password
+ 'connect-tries 10
+ 'initial-status (append (and emchat-user-meta-web-aware '(web-aware))
+ (and emchat-user-meta-invisible '(invisible))
+ (list (emchat-status-v8
+ emchat-user-initial-status)))))
+ ;; Install incoming handlers
+ (setf (emchat-v8-ctx-incoming-handlers emchat-ctx)
+ (list 'instant-message 'emchat-do-instant-message
+ 'missed-message 'emchat-do-missed-message
+ 'offline-message 'emchat-do-offline-message
+ 'connected 'emchat-do-login-confirm
+ 'status-update 'emchat-do-status-update
+ 'about-general 'emchat-do-about-general
+ 'about-more 'emchat-do-about-more
+ 'about-about 'emchat-do-about-about
+ 'logoff 'emchat-do-forced-logoff
+ 'disconnect 'emchat-do-disconnect
+ 'search-found 'emchat-do-search-found
+ 'search-found-last 'emchat-do-search-found-last
+ 'added-you 'emchat-do-added-you
+ 'auth-request 'emchat-do-auth-request
+ 'auth-accept 'emchat-do-auth-accept
+ 'auth-reject 'emchat-do-auth-reject
+ 'srv-contacterr 'emchat-do-srv-contact-err
+ 'srv-error 'emchat-do-srv-general-err
+ 'new-user 'emchat-world-add-new-user
+ ))
+ ;; Load SXEmacs media streams
+ (when (and emchat-use-sound-flag
+ (featurep 'sxemacs))
+ (emchat-load-media-streams))
+ (emchat-v8-connect emchat-ctx emchat-server emchat-port))))
+
+(autoload 'emchat-wharf-change-messages "emchat-wharf")
+
+(defun emchat-logout ()
+ "Logout ICQ server.
+Remain connected to network and server.
+Don't send logout packet if KILL is non-nil,
+useful for emergency logout when being kicked out by server."
+ (interactive)
+
+ (emchat-log-debug "Logging out ICQ server.")
+ (setq emchat-connected-aliases nil)
+ (emchat-buddy-show-buffer 'new 'no-select)
+ (emchat-change-status "offline" 'no-network)
+ (emchat-keep-alive-stop)
+ (if (and (featurep 'emchat-wharf)
+ (frame-live-p emchat-wharf-frame))
+ (progn
+ (emchat-wharf-change-messages "New" -9999)
+ (emchat-wharf-change-messages "Sys" -9999)))
+ (when emchat-history-enabled-flag
+ (mapcar
+ #'(lambda (alias)
+ (let* ((histf (emchat-world-getf alias 'history))
+ (histb (and histf (find-buffer-visiting histf))))
+ (when histb
+ (with-current-buffer histb
+ (save-buffer)
+ (kill-buffer nil)))))
+ emchat-all-aliases))
+ (when (emchat-connected-p emchat-ctx)
+ (emchat-v8-close emchat-ctx)))
+
+(defvar emchat-contact-list-packets nil
+ "Lists of remaining contact list packets to be sent.
+For experimental purpose only.")
+
+;; Now broken because local contact lists are no longer
+;; supported. `emchat-activate-contact-list' replaces this.
+;;(defun emchat-send-contact-list ()
+;; "Send the whole contact list.
+;;You can resend contact list after `emchat-world-update'."
+;; (interactive)
+
+;; (setq emchat-connected-aliases nil)
+;; (emchat-buddy-show-buffer 'new 'no-select)
+
+;; (emchat-world-update)
+;; ;; Visible
+;; (when emchat-visible-contacts
+;; (emchat-v8-ctx-put-prop emchat-ctx 'visible-list
+;; (mapcar
+;; #'(lambda (v)
+;; (emchat-numeric-uin (emchat-alias-uin v)))
+;; emchat-visible-contacts))
+;; (emchat-v8-snac-cli-addvisible emchat-ctx))
+;; ;; Invisible
+;; (when emchat-invisible-contacts
+;; (emchat-v8-ctx-put-prop emchat-ctx 'invisible-list
+;; (mapcar
+;; #'(lambda (i)
+;; (emchat-numeric-uin (emchat-alias-uin i)))
+;; emchat-invisible-contacts))
+;; (emchat-v8-snac-cli-addinvisible emchat-ctx))
+;; ;; All
+;; (emchat-v8-ctx-put-prop emchat-ctx 'contacts
+;; (mapcar 'emchat-numeric-uin (mapcar 'cadr emchat-world)))
+;; (emchat-v8-snac-cli-add-contact emchat-ctx))
+
+(defun emchat-check-contact-list ()
+ "Checks to ensure local copy of SSI list is up to date."
+ (interactive)
+ (emchat-v8-snac-cli-ssi-checkout emchat-ctx))
+
+(defun emchat-activate-contact-list ()
+ "Activate the server-side contact list."
+ (interactive)
+ (setq emchat-connected-aliases nil)
+ (emchat-buddy-show-buffer 'new 'no-select)
+ (emchat-world-update)
+ ;; Visible
+ (when emchat-visible-contacts
+ (emchat-v8-ctx-put-prop emchat-ctx 'visible-list
+ (mapcar
+ #'(lambda (v)
+ (emchat-numeric-uin (emchat-alias-uin v)))
+ emchat-visible-contacts))
+ ; (emchat-v8-snac-cli-addvisible emchat-ctx)
+ )
+ ;; Invisible
+ (when emchat-invisible-contacts
+ (emchat-v8-ctx-put-prop emchat-ctx 'invisible-list
+ (mapcar
+ #'(lambda (i)
+ (emchat-numeric-uin (emchat-alias-uin i)))
+ emchat-invisible-contacts))
+ ; (emchat-v8-snac-cli-addinvisible emchat-ctx)
+ )
+ ;; All
+ (emchat-v8-ctx-put-prop emchat-ctx 'contacts
+ (mapcar 'emchat-numeric-uin (mapcar 'cadr emchat-world)))
+ (emchat-v8-snac-cli-ssi-activate emchat-ctx))
+
+(defun emchat-keep-alive-start ()
+ "Start keeping alive."
+ (emchat-keep-alive-stop)
+ (start-itimer
+ "emchat keep-alive"
+ (lambda ()
+ (emchat-v8-snac-cli-keepalive emchat-ctx))
+ ;; sending faster won't hurt
+ 60 60))
+
+(defun emchat-keep-alive-stop ()
+ "Stop keeping alive."
+ (let ((itimer (get-itimer "emchat keep-alive")))
+ (when (itimerp itimer)
+ (delete-itimer itimer))))
+
+(defun emchat-add-user (uin)
+ (interactive "sUIN: ")
+ (setq emchat-add-user-p t)
+ (emchat-search-by-uin uin))
+
+(defun emchat-change-user (alias password)
+ "Change user to ALIAS with PASSWORD.
+Need to relogin afterwards."
+ (interactive
+ (append (emchat-completing-aliases "Change to: " 'single)
+ (list (read-passwd "Password: "))))
+ (setq emchat-user-alias alias)
+ (setq emchat-user-password
+ (if (zerop (length password))
+ nil
+ password)))
+
+(defun emchat-auto-away-timeout-set (&optional symbol value)
+ "Set timer for auto-away. See `emchat-auto-away-timeout'."
+ (when (itimerp (get-itimer "emchat auto-away"))
+ (delete-itimer (get-itimer "emchat auto-away"))) ; delete previous
+ (start-itimer
+ "emchat auto-away"
+ (lambda ()
+ ;; auto away for first idle
+ (when (member emchat-user-status '("online" "ffc"))
+ (emchat-log-system "Auto away.")
+ (emchat-change-status "away")
+ (setq emchat-user-auto-away-p t)))
+ value value
+ 'is-idle)
+ (when (itimerp (get-itimer "emchat auto-na"))
+ (delete-itimer (get-itimer "emchat auto-na")))
+ (start-itimer
+ "emchat auto-na"
+ (lambda ()
+ ;; auto na for second idle
+ (when (and emchat-user-auto-away-p
+ (equal emchat-user-status "away"))
+ (emchat-log-system "Auto na.")
+ (emchat-change-status "na")
+ ;; emchat-change-status resets this flag
+ (setq emchat-user-auto-away-p t)))
+ (* 2 value) (* 2 value)
+ nil))
+
+(defcustom emchat-auto-away-timeout 300
+ "*Seconds of inactivity in Emacs before auto-away.
+
+After two times the seconds of auto-away, it goes auto-na.
+See `emchat-auto-away'.
+
+If you set this outside of the custom buffer you _MUST_ use
+`customize-set-variable' and _NOT_ `setq'."
+ :type 'number
+ :set 'emchat-auto-away-timeout-set
+ :initialize 'custom-initialize-default
+ :group 'emchat-option)
+
+(defun emchat-change-idle-timeout (&optional seconds)
+ "Change the number of SECONDS before EMchat will idle to \"away\".
+
+Setting the timeout here does not save the value across emacs sessions.
+To do that, customise the variable, `emchat-auto-away-timeout'."
+ (interactive)
+ (let ((timeout (or seconds
+ (read-number
+ "New idle timeout in seconds [RET for no change]: "
+ nil "0"))))
+ (unless (zerop timeout)
+ (emchat-auto-away-timeout-set nil timeout))))
+
+(defun emchat-send-message-helper (message aliases type log-message)
+ "Send message, url, authorization or others.
+MESSAGE is the message to send.
+ALIASES is a list of aliases/uin to send to.
+TYPE is the type of message in `emchat-v8-message-types'.
+LOG-MESSAGE is a message to put in log.
+
+See `emchat-send-message', `emchat-send-url' and `emchat-authorize'."
+ (when (and emchat-user-auto-away-p
+ (not emchat-auto-reply-p))
+ (emchat-change-status "online"))
+ (add-to-list 'emchat-alias-list-history aliases)
+ (loop for alias in aliases
+ do (add-to-list 'emchat-active-aliases alias)
+ do (if (eq type 'normal)
+ (emchat-v8-send-simple-message
+ emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias)) message)
+ (emchat-v8-send-typed-message
+ emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias)) type message))
+ do (emchat-log-outgoing alias ">>> %s" log-message))
+ (setq emchat-auto-reply-p nil))
+
+(defvar emchat-message-history nil
+ "History of `emchat-send-message' for `completing-read'.")
+
+(defun emchat-send-message (&optional message &rest aliases)
+ "Send an instant message.
+MESSAGE is the message to send.
+ALIASES is a list of aliases/uin to send to.
+
+See `emchat-process-alias-input'."
+ (interactive "P")
+ (let ((prompt
+ (concat "Message"
+ ;; display alias if given
+ (if (car aliases)
+ (concat " to "
+ (substring (format "%s" aliases) 1 -1)))
+ ": ")))
+ (or (stringp message)
+ (setq message
+ (read-from-minibuffer prompt
+ nil nil nil 'emchat-message-history)))
+
+ ;; idea from Erik Arneson <erik@starseed.com>
+ ;; confirm sending a blank message
+ (unless (and (or (zerop (length message))
+ ;; \\W fails with "=)" or "..."
+ (string-match "^[ \t]+$" message))
+ (not (y-or-n-p "Send a blank message? ")))
+ (emchat-process-alias-input 'aliases)
+
+ ;; apply encode only TEXT portion of packet
+ (let ((msg (emchat-splitter message)))
+ (loop for x in msg
+ do (emchat-send-message-helper
+ ;; encoding outgoing but not that to be insert in log buffer
+ (emchat-encode-string x) aliases 'normal x)
+ do (when (and (> (length msg) 1)
+ (not (string= x (car (last msg)))))
+ (sit-for 1)))))))
+
+(defun emchat-send-message-via-mouse (event)
+ ;; Erik Arneson <erik@starseed.com> (from VM)
+ "`emchat-send-message' via mouse."
+ (interactive "e")
+ (set-buffer (window-buffer (event-window event)))
+ (and (event-point event) (goto-char (event-point event)))
+ (if (eq (current-buffer) emchat-buddy-buffer)
+ (emchat-send-message-alias-here)
+ ;; fall through
+ ;; any alias in log-mode format (enclosed by []) can use this
+ (emchat-send-message-alias-around)))
+
+(defvar emchat-url-history nil
+ "History of `emchat-send-url' for `completing-read'.")
+
+(defun emchat-send-url (&optional url description &rest aliases)
+ "Send an url.
+URL is any Internet address.
+DESCRIPTION is the description of url.
+ALIASES is a list of aliases/uin to send to.
+
+See `emchat-process-alias-input'."
+ (interactive "P")
+ (let ((prompt
+ (concat "url"
+ ;; display alias if given
+ (if (car aliases)
+ (concat " to "
+ (substring (format "%s" aliases) 1 -1)))
+ ": ")))
+ (or (stringp url)
+ (setq url
+ (read-from-minibuffer
+ prompt nil nil nil 'emchat-url-history)))
+
+ ;; idea from Erik Arneson <erik@starseed.com>
+ ;; confirm sending a blank url
+ (unless (and (or (zerop (length url))
+ ;; \\W fails with "=)" or "..."
+ (string-match "^[ \t]+$" url))
+ (not (y-or-n-p "Send a blank url? ")))
+ (or description
+ (setq description
+ (read-from-minibuffer
+ "description: " nil nil nil 'emchat-message-history)))
+ (emchat-process-alias-input 'aliases)
+
+ (emchat-send-message-helper
+ (format "%s\xfe%s"
+ ;; encode only to TEXT portions of packet, instead of the whole
+ (emchat-encode-string description)
+ (emchat-encode-string url))
+ aliases 'url (format "%s (%s)" url description)))))
+
+(defun emchat-authorize (alias)
+ "Send authorization to allow adding to contact list.
+ALIAS is an alias/uin."
+ (interactive
+ (list (car (emchat-completing-aliases "Authorisation for: " 'single))))
+ (let (reply)
+ (if (y-or-n-p "Accept the authorisation request? ")
+ (progn
+ (setq reply 1)
+ (emchat-log-buddy-message alias ">>> %s" emchat-auth-accept-reason))
+ (setq reply 0)
+ (emchat-log-buddy-message alias ">>> %s" emchat-auth-reject-reason))
+ (emchat-v8-snac-cli-ssi-auth-reply
+ emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias))
+ reply
+ (if (zerop reply)
+ emchat-auth-reject-reason
+ emchat-auth-accept-reason))))
+
+(defun emchat-auth-request (alias)
+ "Request authorisation from ALIAS."
+ (interactive
+ (list (car (emchat-completing-aliases
+ "Request Authorisation from: " 'single))))
+ (emchat-v8-snac-cli-ssi-send-auth-request
+ emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias))
+ emchat-auth-request-reason)
+ (emchat-log-info "Authorisation requested from: %s" alias))
+
+(defun emchat-request-away (&optional alias)
+ "Request away message from ALIAS."
+ (interactive)
+ (unless alias
+ (setq alias (car (emchat-completing-aliases
+ "Get Away message from: " 'single))))
+ (emchat-send-message-helper
+ "" (list alias) 'get-away "Away message requested"))
+
+(defun emchat-request-na (&optional alias)
+ "Request Not Avaliable message from ALIAS."
+ (interactive)
+ (unless alias
+ (setq alias (car (emchat-completing-aliases
+ "Get Not Available message from: " 'single))))
+ (emchat-send-message-helper
+ "" (list alias) 'get-na "Not Available message requested"))
+
+(defun emchat-request-dnd (&optional alias)
+ "Request Do Not Disturb message from ALIAS."
+ (interactive)
+ (unless alias
+ (setq alias (car (emchat-completing-aliases
+ "Get Do Not Disturb message from: " 'single))))
+ (emchat-send-message-helper
+ "" (list alias) 'get-dnd "Do Not Disturb message requested"))
+
+(defun emchat-request-occ (&optional alias)
+ "Request occupied message from ALIAS."
+ (interactive)
+ (unless alias
+ (setq alias (car (emchat-completing-aliases
+ "Get Occupied message from: " 'single))))
+ (emchat-send-message-helper
+ "" (list alias) 'get-occ "Occupied message requested"))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-register-new-user (password)
+; "Register a new uin with PASSWORD."
+; (interactive (list (read-passwd "Password: " 'confirm)))
+; (emchat-send (emchat-pack-register-new-user password)))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-change-password (password)
+; "Change PASSWORD."
+; (interactive (list (read-passwd "Password: " 'confirm)))
+; (emchat-send (emchat-pack-meta-user-change-password password)))
+
+(defun emchat-search (&optional online first last nick email)
+ "Search for ICQ users.
+
+Optional prefix arg, ONLINE when non-nil means to only return search
+results for ICQ users that are currently online.
+
+Argument FIRST - first name to search for
+Argument LAST - last name to search for
+Argument NICK - nick name to search for
+Argument EMAIL - email address to search for."
+ (interactive "P")
+ (let ((online (if online
+ 1
+ (if current-prefix-arg
+ 1
+ 0)))
+ (first (if (interactive-p)
+ (read-string "First Name [RET for null]: ")
+ (or first "")))
+ (last (if (interactive-p)
+ (read-string "Last Name [RET for null]: ")
+ (or last "")))
+ (nick (if (interactive-p)
+ (read-string "Nick Name [RET for null]: ")
+ (or nick "")))
+ (email (if (interactive-p)
+ (read-string "Email Address [RET for null]: ")
+ (or email ""))))
+ (when (string= "" (concat first last nick email))
+ (error 'invalid-argument "You must provide at least one search term"))
+ (emchat-v8-snac-cli-searchbypersinf
+ emchat-ctx first last nick email online)))
+
+(defun emchat-search-by-uin (uin)
+ "Search user by UIN."
+ (interactive "sUIN: ")
+ (emchat-v8-snac-cli-searchbyuin
+ emchat-ctx (emchat-numeric-uin uin)))
+
+(defun emchat-search-by-email (email)
+ "Search for a user by their EMAIL address."
+ (interactive "sEmail address: ")
+ (emchat-v8-snac-cli-searchbyemail emchat-ctx email))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-search-random-user (group)
+; "Search random user in GROUP."
+; (interactive
+; (list (emchat-completing-read
+; "Random group: "
+; (mapcar 'car emchat-random-groups))))
+; (emchat-send (emchat-pack-search-random-user group)))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-set-random-group (group)
+; "Set random user GROUP."
+; (interactive
+; (list (emchat-completing-read
+; "Random group: "
+; (mapcar 'car emchat-random-groups))))
+; (emchat-send (emchat-pack-set-random-group group)))
+
+(defun emchat-query-info (&optional alias)
+ "Query meta user info.
+ALIAS is an alias/uin."
+ (interactive)
+ (if alias
+ ;; display alias if given
+ (message "Query %s." alias)
+ (setq alias (car (emchat-completing-aliases "Query: " 'single))))
+ (let ((local-info (emchat-world-info alias)))
+ (if local-info
+ (emchat-log-info "Local info:\n%s" local-info)))
+
+ (emchat-v8-snac-cli-metareqinfo
+ emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias))))
+
+(defun emchat-add-to-visible-list (aliases)
+ "Add ALIASES, a list of alias names/UINs, to your visible list."
+ (interactive
+ (list (emchat-completing-aliases "Visible to alias/UIN (RET to send): ")))
+ (let ((uins (mapcar
+ #'(lambda (alias)
+ (emchat-numeric-uin (emchat-alias-uin alias)))
+ aliases)))
+ (emchat-v8-snac-cli-addvisible emchat-ctx uins)
+ (mapcar
+ #'(lambda (alias)
+ (add-to-list 'emchat-visible-contacts alias 'append))
+ aliases)
+ (emchat-log-info "You are now visible to: %s" aliases)
+ (when (y-or-n-p "Do you want this change saved for future sessions ")
+ (customize-save-variable 'emchat-visible-contacts
+ (symbol-value 'emchat-visible-contacts)))))
+
+(defun emchat-add-to-invisible-list (aliases)
+ "Add ALIASES, a list of alias names/UINs, to your invisible list."
+ (interactive
+ (list (emchat-completing-aliases "Invisible to alias/UIN (RET to send): ")))
+ (let ((uins (mapcar
+ #'(lambda (alias)
+ (emchat-numeric-uin (emchat-alias-uin alias)))
+ aliases)))
+ (emchat-v8-snac-cli-addinvisible emchat-ctx uins)
+ (mapcar
+ #'(lambda (alias)
+ (add-to-list 'emchat-invisible-contacts alias 'append))
+ aliases)
+ (emchat-log-info "You are now invisible to: %s" aliases)
+ (when (y-or-n-p "Do you want this change saved for future sessions ")
+ (customize-save-variable 'emchat-invisible-contacts
+ (symbol-value 'emchat-invisible-contacts)))))
+
+(defun emchat-remove-from-visible-list (aliases)
+ "Remove ALIASES, a list of alias names/UINs, from your visible list."
+ (interactive
+ (list (emchat-completing-aliases "Not visible to alias/UIN (RET to send): ")))
+ (let ((uins (mapcar #'(lambda (alias)
+ (emchat-numeric-uin (emchat-alias-uin alias)))
+ aliases))
+ nvis)
+ (mapcar
+ #'(lambda (alias)
+ (setq emchat-visible-contacts
+ (remove alias emchat-visible-contacts)))
+ aliases)
+ (setq nvis
+ (mapcar #'(lambda (alias)
+ (emchat-numeric-uin (emchat-alias-uin alias)))
+ emchat-visible-contacts))
+ (emchat-v8-ctx-put-prop emchat-ctx 'visible-list nvis)
+ (emchat-v8-snac-cli-remvisible emchat-ctx uins)
+ (emchat-log-info "You are no longer visible to: %s" aliases)
+ (when (y-or-n-p "Do you want this change saved for future sessions ")
+ (customize-save-variable 'emchat-visible-contacts
+ (symbol-value 'emchat-visible-contacts)))))
+
+(defun emchat-remove-from-invisible-list (aliases)
+ "Remove ALIASES, a list of alias names/UINs, from your invisible list."
+ (interactive
+ (list (emchat-completing-aliases "Not invisible to alias/UIN (RET to send): ")))
+ (let ((uins (mapcar #'(lambda (alias)
+ (emchat-numeric-uin (emchat-alias-uin alias)))
+ aliases))
+ nvis)
+ (mapcar
+ #'(lambda (alias)
+ (setq emchat-invisible-contacts
+ (remove alias emchat-invisible-contacts)))
+ aliases)
+ (setq nvis
+ (mapcar #'(lambda (alias)
+ (emchat-numeric-uin (emchat-alias-uin alias)))
+ emchat-invisible-contacts))
+ (emchat-v8-ctx-put-prop emchat-ctx 'invisible-list nvis)
+ (emchat-v8-snac-cli-reminvisible emchat-ctx uins)
+ (emchat-log-info "You are no longer invisible to: %s" aliases)
+ (when (y-or-n-p "Do you want this change saved for future sessions ")
+ (customize-save-variable 'emchat-invisible-contacts
+ (symbol-value 'emchat-invisible-contacts)))))
+
+(defun emchat-remove-yourself-from-buddy (alias)
+ "Removes your entry from ALIAS' server side contact list."
+ (interactive
+ (list (emchat-completing-read
+ "UIN: "
+ (mapcar #'number-to-string emchat-world-recently-added-by)
+ #'(lambda (match)
+ (not (or (member match emchat-all-uin)
+ emchat-world-track-all-adds))))))
+ (let ((uin (emchat-numeric-uin (emchat-alias-uin alias))))
+ (emchat-v8-snac-cli-ssi-del-yourself emchat-ctx uin)
+ (emchat-log-info "You have removed yourself from %s's server-side
+contact list. When %1$s cycles their ICQ connection you should
+disappear from their local list as well."
+ alias)
+ (setq emchat-world-recently-added-by
+ (delete (emchat-numeric-uin uin) emchat-world-recently-added-by))
+ (with-current-buffer (find-file-noselect
+ emchat-recently-added-by-filename)
+ (erase-buffer)
+ (mapcar
+ #'(lambda (el)
+ (insert (emchat-stringular-uin el)))
+ emchat-world-recently-added-by)
+ (save-buffer)
+ (kill-buffer nil))))
+
+(autoload 'emchat-wharf-new-frame "emchat-wharf")
+
+(defun emchat-switch-to-buddy-buffer ()
+ "Switches from the log buffer to the buddy buffer."
+ (interactive)
+ (emchat-switch-buffer emchat-buddy-buffer))
+
+(defun emchat-switch-to-log-buffer ()
+ "Switches from the buddy buffer to the log buffer."
+ (interactive)
+ (emchat-switch-buffer emchat-log-buffer))
+
+;;;###autoload
+(defun emchat-show-window ()
+ "Show windows of emchat buffers.
+Make them if not yet done.
+See `emchat-buddy-buffer' and `emchat-log-buffer'."
+ (interactive)
+ (unless (frame-live-p emchat-frame)
+ (setq emchat-frame
+ (if (and emchat-start-in-new-frame
+ (device-on-window-system-p))
+ (new-frame '((name . "EMchatLog")))
+ (last-nonminibuf-frame))))
+ (when (device-on-window-system-p)
+ (select-frame emchat-frame))
+ (emchat-buddy-show-buffer)
+ (if emchat-status-use-gutter
+ (progn
+ (set-specifier top-gutter-visible-p t emchat-frame)
+ (emchat-update-tab-in-gutter))
+ (emchat-status-show-buffer))
+ (emchat-log-show-buffer)
+ (set-window-buffer nil emchat-buddy-buffer)
+ (delete-other-windows)
+ (set-window-buffer
+ (split-window nil emchat-buddy-window-width t) emchat-log-buffer)
+ (if emchat-status-use-gutter
+ (emchat-switch-buffer emchat-log-buffer)
+ (set-window-buffer nil emchat-status-buffer)
+ (set-window-buffer
+ (split-window nil emchat-status-window-height) emchat-buddy-buffer)
+ (emchat-switch-buffer emchat-log-buffer))
+ (save-excursion
+ (if emchat-wharf-frame-use-p
+ (emchat-wharf-new-frame)))
+ (focus-frame emchat-frame))
+
+(defun emchat-hide-window ()
+ "Hide windows of emchat buffers."
+ (interactive)
+ (delete-other-windows)
+ (loop for each in '(emchat-buddy-buffer
+ emchat-log-buffer
+ emchat-status-buffer
+ emchat-debug-buffer)
+ do (when (buffer-live-p (symbol-value each))
+ (bury-buffer (symbol-value each))))
+ (bury-buffer)
+ (when emchat-status-use-gutter
+ (set-specifier top-gutter-visible-p nil emchat-frame)))
+
+(defun emchat-window-hidden-p ()
+ "Returns non-nil when the EMchat buffers are hidden."
+ (if (or (get-buffer-window emchat-log-buffer emchat-frame)
+ (get-buffer-window emchat-buddy-buffer emchat-frame)
+ (get-buffer-window emchat-status-buffer emchat-frame))
+ nil
+ t))
+
+;;; Code - log:
+
+;; message history buffer
+
+(defun emchat-alias-around ()
+ "Return an alias/uin on current line or lines before.
+If called interactively, display and push alias into `kill-ring'."
+ (interactive)
+ (save-excursion
+ (outline-back-to-heading)
+ (looking-at "^...:.. \\[\\([^]]+\\)\\]")
+ (let ((alias (match-string 1)))
+ (cond
+ ((or (member alias emchat-all-aliases)
+ (emchat-valid-uin-p alias))
+ (when (interactive-p)
+ (message alias)
+ (kill-new alias))
+ alias)
+ (t (error "No valid alias/uin found"))))))
+
+(defun emchat-oops ()
+ "Oops that message went to the wrong person.
+
+When you accidently send a message to the wrong person, `emchat-oops'
+can be used to send the original message to the correct person and
+send the wrong person an explanation. The explanation sent is the
+value of `emchat-oops-msg-wrong-recipient'.
+
+You will be prompted for the new contact to send to."
+ (interactive)
+ (let ((message (emchat-log-around))
+ (alias (emchat-alias-around)))
+ (emchat-send-message emchat-oops-msg-wrong-recipient alias)
+ (emchat-send-message message)))
+
+(defun emchat-forward-message-around (&optional no-header)
+ "Forward message around
+Non-nil NO-HEADER means avoid prefixing message with original sender's
+info.
+ALIASES is a list of aliases/uin to send to.
+
+See `emchat-process-alias-input'."
+ (interactive "P")
+ (let* ((message (emchat-log-around))
+ (alias (emchat-alias-around))
+ (uin (emchat-alias-uin alias)))
+ (emchat-send-message
+ (concat
+ (if (not no-header)
+ (format "%s (ICQ#%s) Wrote:\n" alias uin))
+ message))))
+
+(defun emchat-forward-message-around-without-header ()
+ "See `emchat-forward-message-around'."
+ (interactive)
+ (emchat-forward-message-around 'no-header))
+
+(defun emchat-select-alias-around ()
+ "See `emchat-group-select-aliases' and `emchat-alias-around'."
+ (interactive)
+ (emchat-group-select-aliases 'toggle (emchat-alias-around)))
+
+(defun emchat-send-message-alias-around ()
+ "See `emchat-send-message' and `emchat-alias-around'."
+ (interactive)
+ (emchat-log-mark 'read)
+ (when emchat-wharf-frame-use-p
+ (emchat-wharf-dec-messages))
+ (emchat-send-message nil (emchat-alias-around)))
+
+(defun emchat-send-url-alias-around ()
+ "See `emchat-send-url' and `emchat-alias-around'."
+ (interactive)
+ (emchat-log-mark 'read)
+ (when emchat-wharf-frame-use-p
+ (emchat-wharf-dec-messages))
+ (emchat-send-url nil nil (emchat-alias-around)))
+
+(defun emchat-authorize-alias-around ()
+ "See `emchat-authorize' and `emchat-alias-around'."
+ (interactive)
+ (emchat-authorize (emchat-alias-around)))
+
+(defun emchat-query-info-alias-around ()
+ "See `emchat-query-info' and `emchat-alias-around'."
+ (interactive)
+ (emchat-query-info (emchat-alias-around)))
+
+;;; Code - buddy:
+
+;; contact list (list of aliases) buffer
+
+(defun emchat-alias-here ()
+ "Return an alias/uin on current line.
+Leading or trailing whitespace are ignored.
+If called interactively, display and push alias into `kill-ring'."
+ (interactive)
+ (save-excursion
+ (end-of-line)
+ (let ((alias
+ (buffer-substring
+ (progn
+ (beginning-of-line)
+ (skip-chars-forward "[ \t]")
+ (point))
+ (progn
+ (end-of-line)
+ (skip-chars-backward "[ \t]")
+ (point)))))
+ (cond
+ ((or (member alias emchat-all-aliases)
+ (emchat-valid-uin-p alias))
+ (when (interactive-p)
+ (message alias)
+ (kill-new alias))
+ alias)
+ (t (error "No valid alias/uin found"))))))
+
+(defun emchat-select-alias-here (action)
+ "See `emchat-group-select-aliases' and `emchat-alias-here'.
+Nil or 'toggle ACTION means toggle selection for alias here.
+`numberp' action or digit arguments (press \\[digit-argument] before this
+command) means select the number of next/previous aliases.
+'toggle-all ACTION or prefix argument (press \\[universal-argument] before this command) means
+toggle selections for all aliases in view.
+'deselect-all or other non-nil ACTION or negative argument (press
+\\[negative-argument] before this command) means deselect for all aliases
+in view.
+
+See `emchat-buddy-select-all-in-view'."
+ (interactive
+ (list (cond
+ ((not current-prefix-arg) 'toggle)
+ ((eq '- current-prefix-arg) 'deselect-all)
+ ((numberp current-prefix-arg) current-prefix-arg)
+ (t 'toggle-all))))
+ (cond
+ ((or (not action) (eq action'toggle))
+ (emchat-group-select-aliases 'toggle (emchat-alias-here))
+ (forward-line))
+ ((and (numberp action) (zerop action))) ; recurrsion done
+ ((natnump action)
+ (emchat-group-select-aliases 'select (emchat-alias-here))
+ (forward-line 1)
+ (emchat-select-alias-here (1- action)))
+ ((numberp action) ; negative digit
+ (emchat-group-select-aliases 'select (emchat-alias-here))
+ (forward-line -1)
+ (emchat-select-alias-here (1+ action)))
+ ((eq action 'toggle-all)
+ (emchat-buddy-select-all-in-view 'toggle))
+ ((eq action 'deselect-all)
+ (emchat-buddy-select-all-in-view nil))))
+
+(defun emchat-send-message-alias-here ()
+ "See `emchat-send-message' and `emchat-alias-here'."
+ (interactive)
+ (emchat-send-message nil (emchat-alias-here)))
+
+(defun emchat-send-url-alias-here ()
+ "See `emchat-send-url' and `emchat-alias-here'."
+ (interactive)
+ (emchat-send-url nil nil (emchat-alias-here)))
+
+(defun emchat-authorize-alias-here ()
+ "See `emchat-authorize' and `emchat-alias-here'."
+ (interactive)
+ (emchat-authorize (emchat-alias-here)))
+
+(defun emchat-query-info-alias-here ()
+ "See `emchat-query-info' and `emchat-alias-here'."
+ (interactive)
+ (emchat-query-info (emchat-alias-here)))
+
+;; Default toolbar button
+(defun emchat-toolbar-login ()
+ "Log into ICQ from the toolbar."
+ (interactive)
+ (call-interactively #'emchat-login))
+
+(defvar emchat-toolbar-icon
+ (toolbar-make-button-list
+ (expand-file-name "mini-logo.png" emchat-glyph-dir))
+ "EMchat button for the default toolbar.")
+
+(defvar emchat-toolbar-spec
+ (vector emchat-toolbar-icon
+ 'emchat-toolbar-login
+ t
+ "Waste time with EMchat")
+ "EMchat default toolbar spec.")
+
+(defun emchat-add-to-toolbar ()
+ "Adds the EMchat button to the default toolbar."
+ (let ((origbar (specifier-instance default-toolbar
+ (selected-window)))
+ (spec emchat-toolbar-spec))
+ (or (ignore-errors (toolbar-find-button emchat-toolbar-icon))
+ (set-specifier default-toolbar
+ (toolbar-add-item origbar spec 'right)
+ 'global))))
+
+;;; Code - footer:
+
+;; otherwise sending large contact list leads to significant delay
+(byte-compile 'emchat-pack-contact-list)
+
+;; Start the idle timer
+(emchat-auto-away-timeout-set nil emchat-auto-away-timeout)
+;; Install bindings
+(emchat-install-bindings 'emchat-prefix-key emchat-prefix-key)
+;; Add our button to the default toolbar
+(when (and (featurep 'toolbar)
+ (featurep 'png)
+ (device-on-window-system-p))
+ (emchat-add-to-toolbar))
+;; Pre-load the saved recent-adds
+(with-current-buffer (find-file-noselect emchat-recently-added-by-filename)
+ (while (re-search-forward "\\(\\w+\\)" nil t)
+ (add-to-list 'emchat-world-recently-added-by
+ (string-to-number (match-string 1))))
+ (kill-buffer nil))
+;; Finally, run the load hook
+(run-hooks 'emchat-load-hook)
+
+(provide 'emchat)
+
+;;; emchat.el ends here
+
--- /dev/null
+\input texinfo @c emchat.texi -*-TeXinfo-*-
+@c Copyright (C) 2000 - 2007 Steve Youngs
+@c %**start of header
+@setfilename emchat.info
+@settitle An Instant Messaging Client for (S)XEmacs.
+@finalout
+@setchapternewpage odd
+@c %**end of header
+@set EDITION 1.2
+@set UPDATED Nov 13, 2007
+
+@include emchat-version.texi
+
+@dircategory Lisp
+@direntry
+* EMchat: (emchat). An Instant Messaging Client for SXEmacs
+@end direntry
+
+@ifinfo
+This manual documents EMchat, an instant messaging client for SXEmacs.
+It corresponds to EMchat version @value{VERSION}.
+
+The manual was last updated @value{UPDATED}.
+@end ifinfo
+
+@titlepage
+@title EMchat
+@subtitle Yet another instant messaging client
+@subtitle Edition @value{EDITION}, for EMchat Version @value{VERSION}
+@author by Steve Youngs
+
+@end titlepage
+Copyright @copyright{} 2000 - 2007 Steve Youngs.
+
+@contents
+
+@node Top, Overview, (dir), (dir)
+
+@ifinfo
+This manual documents EMchat, an instant messaging client for SXEmacs.
+It corresponds to EMchat version @value{VERSION}.
+
+The manual was last updated @value{UPDATED}.
+@end ifinfo
+
+This manual is far from finished. Actually, it hasn't even been started
+yet. At this stage you would be better off looking at the source .el
+files to answer your questions. You are very welcome to direct any
+questions to either @email{emchat-users@@emchat.org, the EMchat Users
+mailing list} or to me at @email{steve@@emchat.org, Steve Youngs}.
+
+
+@menu
+* Overview:: A brief introduction.
+* Concept Index:: Go here to find what you're after.
+@end menu
+
+
+@node Overview, Concept Index, Top, Top
+@chapter Overview
+@cindex overview
+EMchat is an instant messaging client, written in elisp. It @emph{only}
+runs in SXEmacs or XEmacs. So all of you die hard GNU/Emacs users, you'll just
+have to install that other breed of emacsen. You never know, you
+might even like it. Of course this is GPL software, so you are quite
+welcome to port it.
+
+Now you have one more reason to @emph{not} leave SXEmacs.
+
+@node Concept Index, , Overview, Top
+@unnumbered Concept Index
+
+@printindex cp
+
+@contents
+
+@bye
--- /dev/null
+/* XPM */
+static char *file[] = {
+"32 32 169 2",
+".. c #000000",
+".# c #000500",
+".a c #050505",
+".b c #00000b",
+".c c #0b000b",
+".d c #0b0b0b",
+".e c #000011",
+".f c #001100",
+".g c #001101",
+".h c #001111",
+".i c #110000",
+".j c #110011",
+".k c #1d0e1d",
+".l c #111111",
+".m c #171717",
+".n c #161c1c",
+".o c #111122",
+".p c #112211",
+".q c #112222",
+".r c #221100",
+".s c #221111",
+".t c #331111",
+".u c #331c11",
+".v c #221122",
+".w c #222211",
+".x c #332211",
+".y c #222222",
+".z c #2d2d2d",
+".A c #222233",
+".B c #2d2d33",
+".C c #223322",
+".D c #223333",
+".E c #332222",
+".F c #332233",
+".G c #332d33",
+".H c #333322",
+".I c #333333",
+".J c #333833",
+".K c #383338",
+".L c #393939",
+".M c #3e383e",
+".N c #333344",
+".O c #334433",
+".P c #334444",
+".Q c #3e4444",
+".R c #443311",
+".S c #552211",
+".T c #443e3e",
+".U c #552222",
+".V c #553322",
+".W c #5a3822",
+".X c #443344",
+".Y c #443e44",
+".Z c #4f442d",
+".0 c #444433",
+".1 c #444444",
+".2 c #454545",
+".3 c #444944",
+".4 c #444949",
+".5 c #494444",
+".6 c #494449",
+".7 c #4f4f44",
+".8 c #494949",
+".9 c #494f49",
+"#. c #4f4f49",
+"## c #444455",
+"#a c #445544",
+"#b c #4f5a4f",
+"#c c #445555",
+"#d c #554444",
+"#e c #554455",
+"#f c #555544",
+"#g c #555555",
+"#h c #556655",
+"#i c #556666",
+"#j c #5a6969",
+"#k c #664444",
+"#l c #665566",
+"#m c #666655",
+"#n c #66665a",
+"#o c #666671",
+"#p c #666677",
+"#q c #667166",
+"#r c #667766",
+"#s c #667777",
+"#t c #776666",
+"#u c #716671",
+"#v c #776677",
+"#w c #717166",
+"#x c #777766",
+"#y c #717171",
+"#z c #777777",
+"#A c #71717c",
+"#B c #717c71",
+"#C c #7c717c",
+"#D c #7c7c7c",
+"#E c #777788",
+"#F c #7c7c88",
+"#G c #778877",
+"#H c #778888",
+"#I c #884433",
+"#J c #885533",
+"#K c #995533",
+"#L c #887777",
+"#M c #aa5544",
+"#N c #887788",
+"#O c #aa8866",
+"#P c #cc8877",
+"#Q c #dd8866",
+"#R c #888888",
+"#S c #888893",
+"#T c #888899",
+"#U c #889388",
+"#V c #889988",
+"#W c #889999",
+"#X c #938893",
+"#Y c #998899",
+"#Z c #939388",
+"#0 c #999988",
+"#1 c #939393",
+"#2 c #939e93",
+"#3 c #939e9e",
+"#4 c #999999",
+"#5 c #9e9e9e",
+"#6 c #99aa99",
+"#7 c #aa9999",
+"#8 c #aa99aa",
+"#9 c #aaaaaa",
+"a. c #aaaabb",
+"a# c #aabbaa",
+"aa c #aabbbb",
+"ab c #bbaaaa",
+"ac c #bbaabb",
+"ad c #bbbbaa",
+"ae c #bbbbbb",
+"af c #bbccbb",
+"ag c #ddbb88",
+"ah c #c4b5b5",
+"ai c #ccbbbb",
+"aj c #eebb99",
+"ak c #ffbbaa",
+"al c #ccbbcc",
+"am c #ccccbb",
+"an c #eecc88",
+"ao c #ffcc99",
+"ap c #cccccc",
+"aq c #ccccdd",
+"ar c #ccddcc",
+"as c #ccdddd",
+"at c #ddcccc",
+"au c #ddccdd",
+"av c #ddddcc",
+"aw c #dddddd",
+"ax c #ddddee",
+"ay c #ddeedd",
+"az c #ddeeee",
+"aA c #eedddd",
+"aB c #eeddee",
+"aC c #eeeedd",
+"aD c #e2e2e2",
+"aE c #eeeeee",
+"aF c #eeeeff",
+"aG c #eeffee",
+"aH c #eeffff",
+"aI c #ffeeee",
+"aJ c #ffeeff",
+"aK c #ffffee",
+"aL c #ffffff",
+"aM c #b2c0dc",
+"#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g",
+"#g..............................................................",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaM#3#5#1#U#q#uaMaMaMaMaMaMaM#u#F.J",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMapaIawawavaual#6aMaMaMaMaMaM#8aw.7.Y",
+"#g..aMaMaMaMaMaMaMaM#6alaJaCayaAawawawauauar#9#8aMaMaeaJaJaL#b.5",
+"#g..aMaMaMaMaMaMaM#8aEaGazaEaxayawawawasasauaqaa#6#8aLaHaLaL#o.3",
+"#g.eaMaMaMaMalaEaGaFaFaEazaBaBayayawawawasauauawaLaLaLaLaH.N#C.3",
+"#g..aMaMabavaGaIaIaEaEaEaBaCayaBaAawawawauavaEaJaLaLaLaL#7.C#D.6",
+"#g.JaKaLaLaKaKaJaIaEaEaIaEaCaCaBaAawawawaLaKaLaLaLaLaKaL.v#m#R.6",
+"#g.BaLaLaHaJaJaGaGaJaFaEaEaEaEayayaxaBaHaLaLaLaLaLaLaLaL.O#p#S.3",
+"#g...IaHaLaLaJaGaGaFaEaGaGaEaEazaGaLaLaHaLaLaLaLaHaLaL#G#h#E#X.4",
+"#g..#i.saLaKaKaJaIaEaEaIaEaEawaBaLaLaKaLaLaKaLaLaBam#r.s#v#R#Z.6",
+"#g..aMaM.XaLaKaJaJaGaEaEaBaEaLaJalae#a.v.i.l.p.E.1.1#f#l#Yae#Z.6",
+"#g..aMaM#c.IaLaHaGaFaFawaGac.I.D.h.v.I.O#h#v#z#G#H#R#R#Va#au#1.4",
+"#g..aMaMaMaM#gaHaHaJ###VayaBaEayazaEaEazayaBaBayayaBaxayawaw#1.4",
+"#g..aMaMaMaM.p#vaJaGaE.FaJaGaGaIaEaEaEaEaBaEayaBaBayawawawaw#Z.T",
+"#g..aMaMaMaMaMaM#YaKaGaI#Y.0aGaIaIaEaEaIaEaCaCaBaBayayaAawaw.d.I",
+"#g..aM#6#6#L#Pajag#Qaoananaoaoananaoaoananaoaoananaoaoananao#O.Z",
+"#g..aMaMaMaM#k.V.R.s.j.f.f.j.j.f.w.s.s.w.w.s.s.w.w.s.s.f.f.j.c.#",
+"#g..aMaM.F.C.C.F.F.C.2#Y#Y#V#0#Y#tadadacacadadacacad#9.j#Y#V#n.G",
+"#g..aMaMaMaMaMaMaMaMaM#RauaEaEaIaEa#awaEaEaEaEaBaB#maeauatap#y.m",
+"#g..aMaMaMaMaMaMaMaMaMaM.fauaFaGaEaE.IaraGaEaEaE...oawararaq.b.n",
+"#g..aMaMaMaMaMaMaMaMaMaMaM#zaBaEaEaEaEay#WaFap.hawawawas.f.gaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaM.paAaEaEaEaB#v#r..#Nawawaw#g#eaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaM#eaAaEaEaBaBayawaAaA#R.yaMaMaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaM.CaEaEaEazaBaBay.y.gaMaMaMaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaMaM.laEaEazaE#g..aMaMaMaMaMaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM.1aIaEam..#laMaMaMaMaMaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM.j..#faMaMaMaMaMaMaMaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM#6#c#8aMaMaMaMaMaMaMaMaMaM"};
--- /dev/null
+/* XPM */
+static char *file[] = {
+"32 32 16 1",
+". c #ffffff",
+"# c #b6aeb6",
+"a c #beb6be",
+"b c #a6a2a6",
+"c c #000000",
+"d c #aeaeae",
+"e c #a6a6a6",
+"f c #aeaeb6",
+"g c #969696",
+"h c #000808",
+"i c #a69ea6",
+"j c #8e8a8e",
+"k c #fffbff",
+"l c #080408",
+"m c #9e9a9e",
+"n c #a6798e",
+"................................",
+".#a#ba###b#b##a###b#b##a#b#b####",
+".bdadaaaad#aaaaaaad#aaaaaaad#aaa",
+".baeadaafaaaefdaaeabaafdaaeabaaa",
+".adddadddadddaadd#daadaadaaadad#",
+".#addaaddaddadddfa#d#faaaddaadfb",
+".bebbbebaebaba#ababbaebdeaadba#a",
+".bbbbbeb#bebadd#babbaeeba#a#bafa",
+".#aaafaaeaa#abdafeddbdf#abbaabab",
+".gbbbbeeaebee##ab#bbchhbe#aabaaf",
+".beccccccc.edb##babbcccbbbccbafa",
+".bbccccccc.#dbebbbab...##cccebbb",
+".bbccc.bbbbhhcbbchbbchh#cccccheb",
+".gbhcc.b#bbccc.ccc.bcccbhccccc##",
+".bbcccccchbbccccc.bbcccbbccc..#b",
+".bbcccccccbbcccc..bbcccbbcccbbbb",
+".bbccc....bbbcccbbbbcccbbcccbbbb",
+".ggccc.gbbgbbcccgbbgcccbbcccgbbb",
+".bbccc.bbbbbcccc.bbbcccbbcccbbbb",
+".bbccccccccbccccccbbcccbbcccccbb",
+".ggcccccccccccbcccggcccbbbccccbb",
+".ggg..........bb...g...gbbi...bi",
+".bbbbbbbgbbbbggbbgbbgbbbbggbbgbg",
+".bibbbbbgbbbbgjgbgbigibibjggbggg",
+".ggggjggbggjggibgiggigggggbigiib",
+".ggiggijgigbijgjjgijgigiigggjggg",
+".gjgggjgggiigggggjggggiiggggggjg",
+".gggiggiiggggiijgggiijgggiiggiii",
+".gjgjgjjigggggigjigggigigggggjij",
+"kggggggggggggjgjggggggjgggggjmgg",
+".jgmmggggggggngggmmmggngggnggggg",
+".ggjngggngngjgggnggjjggngggngjjj"};
--- /dev/null
+/* XPM */
+static char *file[] = {
+"28 28 2 1",
+". c #b2b2b2 s backgroundToolBarColor",
+"# c #000000",
+"............................",
+"............................",
+"............................",
+"............................",
+"........##########..........",
+".......##.#.#.#.#.#.........",
+"......##.#.#.#.#.#.#........",
+".....##.#.#######.#.#.......",
+".....#.#.#########.#.#......",
+".....##.###########.#.......",
+".....#.#.###.#.###.#.#......",
+".....##.#####.#####.#.#.....",
+".....#.#.###.#.###.#.#.#....",
+".....##.#.#.#.#####.#.#.#...",
+".....#.#.#.#.#####.#.####...",
+".....##.#.#.#####.#.#.......",
+"......##.#.#####.#.#.#......",
+".......##.#.###.#.#.#.......",
+"........##.#####.#.#........",
+".........##.#.#.#.#.#.......",
+".........#.#.#.#.#.#........",
+".........##.###.#...........",
+".........#.#####.#..........",
+".........##.###.#...........",
+"........##.#.#.#.#..........",
+"........#.#.#.#.#.#.........",
+"............................",
+"............................"};
--- /dev/null
+/* XPM */
+static char *file[] = {
+"32 32 79 2",
+".. c #000000",
+".# c #b2c0dc",
+".a c #101000",
+".b c #101800",
+".c c #101f10",
+".d c #101f1f",
+".e c #10381f",
+".f c #1f1f20",
+".g c #201810",
+".h c #202000",
+".i c #202810",
+".j c #204740",
+".k c #206020",
+".l c #20682f",
+".m c #2f2f30",
+".n c #2f3000",
+".o c #2f7f30",
+".p c #2f902f",
+".q c #2fa82f",
+".r c #30302f",
+".s c #30383f",
+".t c #3f204f",
+".u c #3f3000",
+".v c #3f303f",
+".w c #3f3050",
+".x c #3f371f",
+".y c #3f4000",
+".z c #402000",
+".A c #40c84f",
+".B c #4f4f00",
+".C c #4f574f",
+".D c #4f7f9f",
+".E c #50804f",
+".F c #509f60",
+".G c #5f2810",
+".H c #5f500f",
+".I c #5f5030",
+".J c #5f5f60",
+".K c #5faf5f",
+".L c #60474f",
+".M c #70404f",
+".N c #707780",
+".O c #7f402f",
+".P c #7f706f",
+".Q c #7f808f",
+".R c #7fa79f",
+".S c #803f30",
+".T c #808890",
+".U c #8f370f",
+".V c #8f909f",
+".W c #8fa8b0",
+".X c #8fbfcf",
+".Y c #90786f",
+".Z c #908780",
+".0 c #90ff90",
+".1 c #9f7f6f",
+".2 c #9fafa0",
+".3 c #a05f5f",
+".4 c #a06f5f",
+".5 c #a0907f",
+".6 c #a09890",
+".7 c #a0a7c0",
+".8 c #af2000",
+".9 c #b03830",
+"#. c #b07850",
+"## c #b0b7cf",
+"#a c #c0a84f",
+"#b c #c0df9f",
+"#c c #cfa77f",
+"#d c #dfafa0",
+"#e c #e0903f",
+"#f c #e0a810",
+"#g c #e0efe0",
+"#h c #e0f0cf",
+"#i c #e0f7e0",
+"#j c #efb89f",
+"#k c #efeff0",
+"#l c #efffdf",
+"#m c #ffffff",
+".#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#",
+".#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#",
+".#.#.#.#.#.#.##m.C#m#m#m.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#",
+".#.#.#.#.#.##m.i.6#m#m...#.#.#.#.#.#.#.#.#.#.#.#.#.##l#d#m#m...#",
+".#.#.#.#.##m.C.6#m#m.....#.#.#.#.##l.x#m#m.C.#.#.#.##m#m..#m.2..",
+".#.#.#.#.##m#m#m#m.7.....#.#.#.#.##i#m#m#m.C.#.#.#.##m#m...2#m..",
+".#.#.#.#.##m.7##.X.7.....#..#m#m#l.G#m#m.2...#.#.#.##m#m#c#d.C.I",
+".#.#.#.#.##..B.z.z.B.......C#m.6#i#l#l#i.z...#.#.#.##m#m.M.c.b..",
+".#.#...V#m.5.B.G.z.u......#m.R.r#i#c.H#a.G...#.#.#.##c#k.M.b.c..",
+".##g.C#m#m.1.f.d.B.m.....k.R.R.e#c.z.O.z.....#..#m#m..#m#c#d.C.I",
+"#l#g#i#l.k#m.7##.X.7.....m.w.j..#i#c#e#f.x...v..#m#m...C#j#d.L.C",
+"#h.A.E.p...5.B.z.z.B.....s.R.R.r#c.z.z.O.....y..#m#m.y..#d#c.I.M",
+"#b.E.e....#m.q.7.W.V.....s.R.R.r#i#e.B#c.z...y.y.y.y.y..#d#c.I.M",
+"#l.R.p.E..#m.7##.X.T.....m.w.j..#i#e.n#c.x...v.y.j.v.y..#j#d.L.C",
+".0.p.e.e..#m.a##.X.V.....k.R.R.e#l#e#c#c.x...y.y.y.y.v..#c#d.C.I",
+"#b.E.e....#m.s.7.W.V.....s.R.R.r#i#e.B#c.z...y.Q.Q.Z.y..#d#c.I.M",
+"#b.E......#m.w.7.W.V.....s.R.R.r#i#c.B#c.G...y.Q.Q.Z.y..#d#c.I.M",
+"#l.R.p.E..#m.7##.X.V.....k.R.R.e#l#c.n#c.x...y.y.y.y.v..#c#d.C.I",
+"#l.R.p.E..#m.a##.X.T.....k.R.R.e#i#c#c#f.x...v.y.j.v.y..#j#d.L.C",
+"#h.A.E.p..#m.7.7.W.V.....s.R.R.r#i#c.h#a.G...y.y.y.c.y..#d#c.I.M",
+"#g.K.p.p..#m.s.7.W.V.....s.R.R.r#i#c.h#e.z...y.y.y.y.y..#d#c.I.M",
+"#l.R.p.E..#m.7##.X.T.....k.R.R.e#i#c#c#f.x...v.c.c.v.y..#j#d.L.C",
+"#l.R.p.E..#m.7##.X.V.....k.R.R.e#l#c.O#f.x...y.y.y.y.v..#c#d.C.I",
+"#b.E......#m##.7.W.V.....s.R.R.r#i#e#c#e.z...y.3.Y.D.y..#d#c.I.M",
+"#b.E......#m.7.7.W.7.....s.R.R.r#i#e.y.y.G...y.Y.3.4.y..#d#c.I.M",
+"#l.R.p.E...7.B.u.B.w.....k.R.R.e#l#e#c.y.x...y.P.D.D.v...I.c....",
+"#l.R.p.E...7.w.s.u.w.......w.j..#i#c#c.j.x...v.y.j.v.y...C.c....",
+"#h.A.E.p..#m.7.7.W.7.....s.R.R.r#i#c.H.y.G...y.Y.3.D.y..#d#c.I.M",
+".#.#.#.#.##m.q.7.W##...#........#c#c#e#e.z...y.y.y.y.y..........",
+".#.#.#.#.##m.W.X.X.7...#.#.#.#.#.#.....................#.#.#.#.#",
+".#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#",
+".#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#"};
--- /dev/null
+/* XPM */
+static char *file[] = {
+"32 32 47 1",
+". c #101028",
+"# c #101828",
+"a c #181828",
+"b c #101830",
+"c c #181830",
+"d c #182038",
+"e c #182041",
+"f c #202049",
+"g c #202849",
+"h c #202859",
+"i c #283449",
+"j c #383c59",
+"k c #283061",
+"l c #303871",
+"m c #304179",
+"n c #414961",
+"o c #494d61",
+"p c #515569",
+"q c #595d79",
+"r c #697579",
+"s c #384586",
+"t c #38418e",
+"u c #38498e",
+"v c #41498e",
+"w c #41518e",
+"x c #49598e",
+"y c #415196",
+"z c #495196",
+"A c #495996",
+"B c #515d96",
+"C c #59619e",
+"D c #697196",
+"E c #797da6",
+"F c #868696",
+"G c #868aae",
+"H c #9692a6",
+"I c #c7c3c7",
+"J c #c7cbcf",
+"K c #cfcbdf",
+"L c #d7d3d7",
+"M c #d7d7df",
+"N c #dfdbdf",
+"O c #e7e3e7",
+"P c #efebef",
+"Q c #f7f3f7",
+"R c #fffbff",
+"S c #b2c0dc",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
+"SSSSSSSSSSSSc.cehhffooSSSSSSSSSS",
+"SSSSSSSSSSbbhlttuuuusspSSSSSSSSS",
+"SSSSSSSSi.hmttBMNNuuvvssSSSSSSSS",
+"SSSSSSSebkttttMOIImmvvvvqqSSSSSS",
+"SSSSSSibltttttPIIIddvvvvwwSSSSSS",
+"SSSSSp.ktttttuKIJJ##vvvvwwSSSSSS",
+"SSSSScftttttuuCHFFddvvwwwwDDSSSS",
+"SSSSp.lttttuuuum##mmvvwwwwzzSSSS",
+"SSSSifttttuCPPPPQQvvwwwwyyzzSSSS",
+"SSSSbktttuuCs.JJLL##wwwwzzzzSSSS",
+"SSSS.mttuuuusvPLLL##wwyyzzzzSSSS",
+"SSSSbttuuuuuvvQLNN##wwzzzzzzSSSS",
+"SSSSetuuuuuvvvQLNN##yyzzzzzzSSSS",
+"SSSSeuuuuuvvvvQNNN##zzzzzzzzSSSS",
+"SSSScuuuuvvvvvQNOO##zzzzzzAASSSS",
+"SSSSeuuuvvvvvvQNOO##zzzzzzAASSSS",
+"SSSSpmuvvvvvvwQOOO##zzzzAAAASSSS",
+"SSSSSgvvvvvvwwQOOO##zzzzAAAASSSS",
+"SSSSSovvvvvwwwQOPP##zzAAAASSSSSS",
+"SSSSSSlvvvwwwwQPPP##zzAAAASSSSSS",
+"SSSSSSFxvwwwQQQPQQQQAAAACCSSSSSS",
+"SSSSSSSDxwwwy#####aaaaAASSSSSSSS",
+"SSSSSSSSSSwyzzzzzzAAAADDSSSSSSSS",
+"SSSSSSSSSSSBzzzzzzAACCSSSSSSSSSS",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"};
--- /dev/null
+#define brilliant_width 390
+#define brilliant_height 120
+static unsigned char brilliant_bits[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xcf,
+ 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f,
+ 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9,
+ 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf,
+ 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xe0, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f,
+ 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe,
+ 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3,
+ 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f,
+ 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02,
+ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x7f, 0xc7, 0x01,
+ 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x04, 0x00, 0x00, 0x00,
+ 0x81, 0x0b, 0x82, 0x73, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f,
+ 0xe3, 0x00, 0x70, 0x71, 0x80, 0x00, 0x00, 0x00, 0x01, 0x20, 0x08, 0x00,
+ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x42, 0xc6,
+ 0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00,
+ 0x00, 0x41, 0x0c, 0x02, 0x21, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x63, 0x00, 0x88, 0x41, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x09,
+ 0x07, 0x04, 0x5c, 0x3c, 0xb6, 0xe1, 0x00, 0xe0, 0x83, 0x07, 0x00, 0x42,
+ 0xea, 0x70, 0xe9, 0xe0, 0xe1, 0x03, 0x00, 0x00, 0x00, 0x92, 0x74, 0xe0,
+ 0x00, 0x80, 0x40, 0x08, 0x04, 0x12, 0x84, 0xb6, 0xf1, 0xc0, 0xc5, 0x07,
+ 0x00, 0x04, 0x75, 0x00, 0x04, 0x41, 0xe0, 0x80, 0x63, 0x87, 0x0f, 0x20,
+ 0x89, 0x08, 0x04, 0x62, 0x42, 0x6c, 0x11, 0x01, 0x40, 0x40, 0x08, 0x00,
+ 0x12, 0xaa, 0x88, 0x19, 0x11, 0x42, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8c,
+ 0x10, 0x01, 0x80, 0x40, 0x00, 0x04, 0x12, 0x24, 0x6c, 0x09, 0x21, 0x26,
+ 0x04, 0x00, 0x04, 0x55, 0x00, 0x04, 0x40, 0x80, 0x40, 0xc4, 0x08, 0x01,
+ 0xa0, 0x4a, 0x10, 0x04, 0x41, 0x81, 0x24, 0x09, 0x02, 0x40, 0x20, 0x10,
+ 0x00, 0x1e, 0x92, 0x04, 0x09, 0x01, 0x42, 0x00, 0x80, 0x1f, 0x00, 0x10,
+ 0x84, 0x08, 0x02, 0x80, 0x80, 0x07, 0x04, 0x0c, 0x3c, 0x24, 0x01, 0x11,
+ 0x24, 0x00, 0x00, 0x04, 0x49, 0x00, 0x04, 0x40, 0x80, 0x20, 0x48, 0x08,
+ 0x01, 0xa0, 0xca, 0x1f, 0x04, 0x01, 0x81, 0x24, 0xf9, 0x03, 0x40, 0x20,
+ 0x10, 0x00, 0x12, 0x92, 0x04, 0x08, 0xe1, 0x43, 0x00, 0x00, 0x00, 0x00,
+ 0x10, 0x84, 0xf8, 0x03, 0x80, 0x00, 0x08, 0x04, 0x12, 0x24, 0x24, 0xf1,
+ 0x11, 0xc0, 0x03, 0x00, 0x04, 0x49, 0x00, 0x04, 0x40, 0x80, 0xe0, 0x4f,
+ 0x08, 0x01, 0x40, 0x44, 0x00, 0x04, 0x01, 0x81, 0x24, 0x09, 0x00, 0x40,
+ 0x20, 0x10, 0x00, 0x42, 0x82, 0x04, 0x08, 0x11, 0x42, 0x00, 0x00, 0x00,
+ 0x00, 0x10, 0x84, 0x08, 0x00, 0x80, 0x40, 0x08, 0x04, 0x12, 0x84, 0x24,
+ 0x09, 0x11, 0x00, 0x04, 0x00, 0x04, 0x41, 0x00, 0x04, 0x40, 0x80, 0x20,
+ 0x40, 0x08, 0x01, 0x40, 0x84, 0x10, 0x04, 0x42, 0x42, 0x24, 0x11, 0x02,
+ 0x40, 0x44, 0x08, 0x00, 0x42, 0x82, 0x08, 0x09, 0x11, 0x43, 0x04, 0x00,
+ 0x00, 0x00, 0x10, 0x84, 0x10, 0x02, 0x80, 0xc0, 0x08, 0x04, 0x21, 0x84,
+ 0x24, 0x89, 0x21, 0x24, 0x04, 0x00, 0x04, 0x41, 0x00, 0x08, 0x41, 0x80,
+ 0x40, 0x48, 0x08, 0x11, 0x40, 0x04, 0x0f, 0x1f, 0x3c, 0x3c, 0x6e, 0xe3,
+ 0x01, 0x80, 0x83, 0x07, 0x00, 0x7f, 0xc7, 0xf1, 0x9c, 0xe3, 0x86, 0x03,
+ 0x00, 0x00, 0x00, 0x7c, 0xce, 0xe1, 0x01, 0x00, 0x41, 0x07, 0x82, 0x73,
+ 0xfe, 0x6e, 0x73, 0xc3, 0xe3, 0x03, 0x00, 0x9f, 0xe3, 0x00, 0xf0, 0xf0,
+ 0xe1, 0x83, 0xe7, 0x1c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x06, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00,
+ 0x00, 0x00, 0xc0, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00,
+ 0xc1, 0x00, 0x00, 0x00, 0x04, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x02,
+ 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x0f, 0x80, 0x73, 0x3c, 0xc6, 0x00,
+ 0x80, 0xc0, 0x81, 0x1c, 0x0e, 0x00, 0x3e, 0x74, 0x70, 0xe0, 0x03, 0x80,
+ 0x0f, 0x0f, 0x3f, 0x3e, 0x8e, 0xf3, 0x30, 0x83, 0x03, 0x00, 0x80, 0x1d,
+ 0x10, 0x70, 0xf0, 0xe0, 0x83, 0x03, 0x00, 0x2e, 0x1e, 0x3b, 0xf8, 0x70,
+ 0xe0, 0x82, 0xc3, 0x0c, 0x00, 0x00, 0x01, 0x01, 0x00, 0x21, 0x42, 0x84,
+ 0x00, 0x80, 0x00, 0x81, 0x04, 0x11, 0x00, 0x04, 0x8c, 0x40, 0x10, 0x02,
+ 0x40, 0x88, 0x10, 0x04, 0x04, 0x04, 0x09, 0xa1, 0x44, 0x04, 0x00, 0x00,
+ 0x23, 0x10, 0x88, 0x08, 0x11, 0x42, 0x04, 0x00, 0x31, 0x21, 0x46, 0x84,
+ 0x40, 0x10, 0x43, 0x84, 0x12, 0x00, 0x00, 0x01, 0x01, 0x00, 0x21, 0x81,
+ 0x84, 0x00, 0x80, 0x00, 0x81, 0x82, 0x20, 0x00, 0x04, 0x84, 0x40, 0x10,
+ 0x00, 0x40, 0x40, 0x20, 0x04, 0x04, 0x24, 0x01, 0x61, 0x20, 0x08, 0x00,
+ 0x00, 0x41, 0x10, 0x04, 0x01, 0x11, 0x20, 0x08, 0x80, 0xa0, 0x40, 0x42,
+ 0x04, 0x40, 0x08, 0x22, 0x88, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x12,
+ 0x81, 0x84, 0x00, 0x80, 0x00, 0x81, 0x81, 0x3f, 0x00, 0x04, 0x84, 0x40,
+ 0xe0, 0x01, 0x80, 0x47, 0x20, 0x04, 0x04, 0x24, 0xf1, 0x21, 0xe0, 0x0f,
+ 0x00, 0x00, 0x41, 0x10, 0xfc, 0xf1, 0xe1, 0xe1, 0x0f, 0x80, 0x80, 0x40,
+ 0x42, 0x78, 0x40, 0x08, 0xe2, 0x8f, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
+ 0x12, 0x81, 0x84, 0x00, 0x80, 0x00, 0x81, 0x82, 0x00, 0x00, 0x04, 0x84,
+ 0x40, 0x00, 0x02, 0x00, 0x48, 0x20, 0x04, 0x04, 0xa8, 0x08, 0x21, 0x20,
+ 0x00, 0x00, 0x00, 0x41, 0x10, 0x04, 0x08, 0x01, 0x22, 0x00, 0x80, 0x80,
+ 0x40, 0x42, 0x80, 0x40, 0x08, 0x22, 0x80, 0x00, 0x00, 0x00, 0x01, 0x01,
+ 0x00, 0x0c, 0x42, 0xc4, 0x00, 0x80, 0x00, 0x81, 0x04, 0x21, 0x00, 0x44,
+ 0x84, 0x40, 0x10, 0x02, 0x40, 0x88, 0x10, 0x04, 0x44, 0xd8, 0x88, 0x21,
+ 0x40, 0x08, 0x03, 0x00, 0x23, 0x10, 0x08, 0x89, 0x11, 0x42, 0x08, 0x00,
+ 0x21, 0x21, 0x42, 0x84, 0x40, 0x10, 0x43, 0x88, 0x00, 0x00, 0xc0, 0xc7,
+ 0x07, 0x00, 0x08, 0x3c, 0xb8, 0x01, 0xe0, 0xc3, 0xc7, 0x1c, 0x1e, 0x00,
+ 0x38, 0xce, 0xf1, 0xf1, 0x01, 0xc0, 0x07, 0x0f, 0x1f, 0x38, 0xd8, 0x70,
+ 0xf3, 0x80, 0x07, 0x03, 0x00, 0x1d, 0x7c, 0xf0, 0x70, 0xf3, 0x81, 0x07,
+ 0x00, 0x1e, 0x1e, 0xe7, 0x7c, 0xf0, 0xe1, 0x86, 0xc7, 0x03, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+ 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0xc1, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x40, 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x04,
+ 0x00, 0x00, 0x00, 0xfc, 0xf0, 0xe7, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x40, 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x21, 0x24, 0x09, 0x01, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x3a, 0x00, 0xee, 0x00, 0xe0,
+ 0xd8, 0x86, 0x4b, 0x07, 0x0f, 0x1f, 0x00, 0xb8, 0xf0, 0xd8, 0xc1, 0xc3,
+ 0x07, 0x07, 0x1e, 0x3b, 0x00, 0x08, 0x21, 0x24, 0x09, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x2a, 0x00, 0x44, 0x00,
+ 0x10, 0xb1, 0x45, 0xcc, 0x88, 0x10, 0x02, 0x00, 0xc4, 0x08, 0x31, 0x22,
+ 0x84, 0x00, 0x04, 0x21, 0x46, 0x00, 0x08, 0x21, 0x01, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x24, 0x3f, 0x28,
+ 0x00, 0x08, 0x92, 0x24, 0x48, 0x08, 0x10, 0x02, 0x7e, 0x82, 0x04, 0x12,
+ 0x02, 0x84, 0x00, 0x84, 0x40, 0x42, 0x00, 0x88, 0xe0, 0x01, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x24, 0x00,
+ 0x10, 0x00, 0xf8, 0x93, 0x24, 0x40, 0x08, 0x1f, 0x02, 0x00, 0x82, 0x04,
+ 0x12, 0xc2, 0x87, 0x00, 0x84, 0x40, 0x42, 0x00, 0x78, 0x20, 0x01, 0x01,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20,
+ 0x00, 0x28, 0x00, 0x08, 0x90, 0x24, 0x40, 0x88, 0x10, 0x02, 0x00, 0x82,
+ 0x04, 0x12, 0x22, 0x84, 0x00, 0x84, 0x40, 0x42, 0x00, 0x88, 0x20, 0x04,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+ 0x20, 0x00, 0x44, 0x00, 0x10, 0x92, 0x44, 0x48, 0x88, 0x18, 0x22, 0x00,
+ 0xc4, 0x08, 0x11, 0x22, 0x86, 0x08, 0x04, 0x21, 0x42, 0x00, 0x08, 0x21,
+ 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xc0, 0x71, 0x00, 0xee, 0x00, 0xe0, 0xb9, 0x8d, 0xe7, 0x1c, 0x37, 0x1c,
+ 0x00, 0xb8, 0xf1, 0x38, 0xc7, 0x0d, 0x07, 0x1f, 0x1e, 0xe7, 0x00, 0x1c,
+ 0xf2, 0xc7, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+ 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f,
+ 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc,
+ 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7,
+ 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0xe0, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf,
+ 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f,
+ 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9,
+ 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf,
+ 0x9f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
--- /dev/null
+/* XPM */
+static char *file[] = {
+"32 32 6 1",
+". c #808080",
+"# c #000000",
+"a c #808080",
+"b c #5050ff",
+"c c #ffffff",
+"d c #d0d0d0",
+"................................",
+"................................",
+"..........aaaaaaaaaaaaaaaaaa....",
+"..........aaaaaaaaaaaaaaaaaa....",
+"........aaddddddddddddddddaa##..",
+"........aaddddddddddddddddaa##..",
+"......aaccccccccccccccccaaaa##..",
+"......aaccccccccccccccccaaaa##..",
+"......aacc############ccaaaa##..",
+"......aacc############ccaaaa##..",
+"......aacc##bbbbbbbbbbccaaaa##..",
+"......aacc##bbbbbbbbbbccaaaa##..",
+"......aacc##bbbbbbbbbbccaaaa##..",
+"......aacc##bbbbbbbbbbccaaaa##..",
+"......aacc##bbbbbbbbbbccaaaa##..",
+"......aacc##bbbbbbbbbbccaaaa##..",
+"......aaccccccccccccccccaa##aaaa",
+"......aaccccccccccccccccaa##aaaa",
+"......aa##################aadd##",
+"......aa##################aadd##",
+"....aaccccccccccccccccccaaddaa##",
+"....aaccccccccccccccccccaaddaa##",
+"....aaaa##aa##aa##aa##aa##aaaa##",
+"....aaaa##aa##aa##aa##aa##aaaa##",
+"..aadd##dd##dd##dd##dd##dd####..",
+"..aadd##dd##dd##dd##dd##dd####..",
+"aaccccccccccccccccccccccdd##....",
+"aaccccccccccccccccccccccdd##....",
+"##########################......",
+"##########################......",
+"................................",
+"................................"};
--- /dev/null
+/* XPM */
+static char *logout[] = {
+"32 32 234 2",
+".. c #c7cbc7",
+".# c #bebebe",
+".a c #bebabe",
+".b c #b6babe",
+".c c #bec3c7",
+".d c #bebeb6",
+".e c #b6b6b6",
+".f c #c7c7c7",
+".g c #a6aeae",
+".h c #eff3f7",
+".i c #e7ebef",
+".j c #cfd3d7",
+".k c #cfcfcf",
+".l c #d7d7d7",
+".m c #d7dbd7",
+".n c #dfdfd7",
+".o c #dfe3e7",
+".p c #d7d7cf",
+".q c #717979",
+".r c #515151",
+".s c #a6aaae",
+".t c #a6aaa6",
+".u c #9ea6a6",
+".v c #9ea2a6",
+".w c #9e9ea6",
+".x c #9e9e9e",
+".y c #969a9e",
+".z c #969696",
+".A c #8e9296",
+".B c #8e8e8e",
+".C c #868686",
+".D c #798286",
+".E c #868a86",
+".F c #969a96",
+".G c #515959",
+".H c #494d49",
+".I c #8e928e",
+".J c #9ea29e",
+".K c #414141",
+".L c #494949",
+".M c #383c38",
+".N c #414541",
+".O c #868a8e",
+".P c #8e8e9e",
+".Q c #86869e",
+".R c #797d79",
+".S c #8e8686",
+".T c #aeb2ae",
+".U c #aeb6b6",
+".V c #797d8e",
+".W c #717571",
+".X c #867d79",
+".Y c #697571",
+".Z c #697171",
+".0 c #b6b2be",
+".1 c #efebdf",
+".2 c #e7e7df",
+".3 c #e7e3d7",
+".4 c #dfdbd7",
+".5 c #dfdbcf",
+".6 c #d7d3be",
+".7 c #d7cfc7",
+".8 c #cfcfc7",
+".9 c #cfcbbe",
+"#. c #cfc7be",
+"## c #c7c7be",
+"#a c #c7c3b6",
+"#b c #c7beb6",
+"#c c #bebab6",
+"#d c #beb6ae",
+"#e c #b6aea6",
+"#f c #968e8e",
+"#g c #797979",
+"#h c #383838",
+"#i c #dfd7cf",
+"#j c #beb2ae",
+"#k c #aea6a6",
+"#l c #a69e96",
+"#m c #616161",
+"#n c #867979",
+"#o c #797571",
+"#p c #696979",
+"#q c #696d71",
+"#r c #616561",
+"#s c #595969",
+"#t c #595551",
+"#u c #515571",
+"#v c #494969",
+"#w c #414559",
+"#x c #494551",
+"#y c #968a8e",
+"#z c #b6b2ae",
+"#A c #8e8a86",
+"#B c #9e9a96",
+"#C c #717586",
+"#D c #616579",
+"#E c #515171",
+"#F c #494d79",
+"#G c #494971",
+"#H c #96928e",
+"#I c #303430",
+"#J c #514d49",
+"#K c #9e9eb6",
+"#L c #717196",
+"#M c #71718e",
+"#N c #515586",
+"#O c #494996",
+"#P c #494986",
+"#Q c #49458e",
+"#R c #414161",
+"#S c #202420",
+"#T c #494541",
+"#U c #797996",
+"#V c #aeaab6",
+"#W c #71759e",
+"#X c #595996",
+"#Y c #515596",
+"#Z c #383c9e",
+"#0 c #414596",
+"#1 c #595986",
+"#2 c #696561",
+"#3 c #383c51",
+"#4 c #202020",
+"#5 c #595d59",
+"#6 c #696d8e",
+"#7 c #61618e",
+"#8 c #69699e",
+"#9 c #41459e",
+"a. c #616596",
+"a# c #4949a6",
+"aa c #5959a6",
+"ab c #696db6",
+"ac c #494da6",
+"ad c #4949b6",
+"ae c #383886",
+"af c #a6a2b6",
+"ag c #303449",
+"ah c #303038",
+"ai c #201c18",
+"aj c #515551",
+"ak c #616961",
+"al c #4145b6",
+"am c #5151b6",
+"an c #7175ae",
+"ao c #8e8eb6",
+"ap c #6165ae",
+"aq c #595d8e",
+"ar c #383c69",
+"as c #303051",
+"at c #303030",
+"au c #181818",
+"av c #282c28",
+"aw c #8682ae",
+"ax c #dfdbbe",
+"ay c #303471",
+"az c #181410",
+"aA c #282828",
+"aB c #596159",
+"aC c #495149",
+"aD c #e7dfd7",
+"aE c #8e8ea6",
+"aF c #383479",
+"aG c #282c61",
+"aH c #282c41",
+"aI c #282851",
+"aJ c #aeb2b6",
+"aK c #5155ae",
+"aL c #282c8e",
+"aM c #202449",
+"aN c #383c49",
+"aO c #d7d7be",
+"aP c #e7e3be",
+"aQ c #9692ae",
+"aR c #282871",
+"aS c #aeaea6",
+"aT c #696d69",
+"aU c #595da6",
+"aV c #202486",
+"aW c #282c79",
+"aX c #202049",
+"aY c #868279",
+"aZ c #616969",
+"a0 c #7979b6",
+"a1 c #282896",
+"a2 c #30308e",
+"a3 c #30348e",
+"a4 c #201c8e",
+"a5 c #797971",
+"a6 c #595979",
+"a7 c #7171a6",
+"a8 c #101441",
+"a9 c #61619e",
+"b. c #303496",
+"b# c #181861",
+"ba c #181451",
+"bb c #101038",
+"bc c #797171",
+"bd c #515561",
+"be c #383879",
+"bf c #303069",
+"bg c #202079",
+"bh c #181c69",
+"bi c #100c28",
+"bj c #717169",
+"bk c #101010",
+"bl c #494d96",
+"bm c #494d69",
+"bn c #181c49",
+"bo c #a6a29e",
+"bp c #696961",
+"bq c #ae7969",
+"br c #a68a86",
+"bs c #a66d69",
+"bt c #9e7d69",
+"bu c #9e7969",
+"bv c #8e9659",
+"bw c #96ba20",
+"bx c #8e9a38",
+"by c #716d69",
+"bz c #716969",
+"bA c #516961",
+"bB c #8e8661",
+"bC c #9e968e",
+"bD c #867971",
+"bE c #595951",
+"bF c #415151",
+"bG c #080808",
+"bH c #080400",
+"bI c #100c08",
+"bJ c #696159",
+"bK c #696969",
+"bL c #968e86",
+"bM c #dfdfdf",
+"bN c #515951",
+".....#.#.#.#.a.b.#.#.#.c.#.#.#.#.#.c.c.c.b.e.e.e.b.#.c.f.f.#.a.g",
+".b.h.j.j.j.k.l.l.j.j.l.l.l.l.l.l.o.n.n.m.p.m.l.m.m.m.n.n.n.m.b.q",
+".e.m.A.z.z.A.I.B.A.z.z.z.F.F.z.A.z.A.B.B.D.C.I.I.z.x.y.I.B.I.B.K",
+".e.m.I.A.z.z.A.I.A.A.I.A.A.z.I.B.I.B.B.E.D.D.B.B.F.y.B.C.I.y.E.M",
+".b.m.z.I.z.I.P.O.O.O.C.O.C.C.C.C.B.E.D.C.R.D.C.O.A.O.D.I.F.F.C.M",
+".U.l.x.A.B.O.O.D.D.C.C.C.R.q.D.C.C.V.V.q.q.V.D.C.O.D.C.P.z.z.B.K",
+".0.l.x.P.D.D.1.1.1.1.2.3.n.n.5.m.6.7.9.8###a.d#c#e.y#g.q.B.x.B#h",
+".U.l.F.B.X.p.1.1.1.i.2.3.o.4#i.m.j.j.9#.#a#b#c#c#e#k.D#m.O.v.C#h",
+"#z.p.A.B.D.1#g#A#B.z#g.V#C#p#D#D#E#F#G#v#v#x#x#x.K#h#H#I.Z.D.Y#I",
+".e.j.O.O#g.1#A.e.e#K#p#D#M#u#N#G#P#P#Q#Q#Q#G#R#x#h#h.z#S#m.q.Y#I",
+".e.j.O.B#g.1#U#k#6#7#Y#9a.a#a#aaabaaacad#0#0af#uagah#yaiaj#qak#I",
+".e.j.B.A.R.2.q#K#W#8#Xacada#aladanaf#Kaoadaeaqarasat#Aau.L#mak#I",
+".U.j.I.A.R.3.QaEawapaaada##8adaladad#K.f.9af#9aFaHaI.Saz.K#m.R.M",
+"aJ.k.A.z.WaD#8#U#Xac#9adab.0aladalalaa.a.p#VaLaLaIaM.Saz.N#r.qaN",
+"aS.8.z.yaT.4#L#Laaacala#adalaUadadadad##.2.0#ZaVaIaXaYaz#T#maT#I",
+"aJ.k.z.IaZ.4#1#X#0#Qa#a#adadabamadada0aOaP##ada1ayaM.Xaz#T#m.Z#I",
+".d.l.A.O.Y.l#1#1aca##9adadadamadadal#iaxaO.c#Za1.a#E#naz.N#maT#I",
+".c.j.I.C.Z.6#N#Na##Qa#a#adadananab#Vax.9#.#Va1a1.QaM.Raz.L#m.Z#h",
+".c.l.I.D.q.7a6#E#Na.#Q#O#Qada0#.aOax.6.9a7aKa4a4#Ea8#oaz#T#m.Z#I",
+".c.p.B.C.q.9#s#s#u#U#Q#Q#9#9#9a9a0aw#W#8b.a1a4b#babbbcaz.N#r.Z#I",
+".f.p.B.O.V#.#t.Gbd#E#s#E#O#P#O#O#F#P#G#u#E#F#P#Pbmbibcbk.K#maT#h",
+".c.m.O.O.R#..z.H.H#T.H#wararbfbfaIaMaMaXbnbna8a8bi#rbcbk.K#m.Y#h",
+"...m.B.O.Rbp#e#e.s#k#l#lbr#Bbsbt#Hbs.S#y.ZaYbwbxbybz#tbk.M#m.Y#h",
+".f.m.I.B.DaTbAbB#l#BbC.z#H#f#A#yaY.DaY#n#oa5bj#2bEbFbGbk.M.GaZat",
+"##.m.z.I.C.X#m#JahaA.L#5.r.r#5ajbpbJbEbKbE#5bIbkazazau#4.N#5.Z#h",
+".f.m.z.P.E.CaTaB.CbL#f#A.S.S.S.X.Xa5#o#objbz#5#5ai#4aA#IajaT.q#I",
+".c.m.z.A.B.I.R.Waj.NaAaibkazbkbkbkbkbkazazauai#S#I.M.H#t.W.C.R#h",
+".c.m.z.z.B.I.E.X#5.H#hat#S#S#S#4#S#SaAaAaAaAah#h.L.r#mbK.D.B.D#h",
+".fbM.y.F.A.z.x.z.D.Wbpak#r#rbp#m#m#r#r#2#rbpbpaT.W.q.E.O.A.z.C.M",
+".c.m.y.z.z.x.v.x.B.C.qa5.R.R.C.C.X.R.q.C.D.D.D.D.S.B.A.z.x.x.C.M",
+"...k.I.I.J.t.v.F.B.E.E.B.z.z.y.J.B.I.I.D.R.R.R.R.R.V.D.C.D.D.Z.M",
+".d#Kat#I#h.M#IaAaA#S#S#SaAaAaAaAaAaAaA#h#Iag#h#I#I#h#h#h#I#IavaA"};
--- /dev/null
+/* XPM */
+static char *file[] = {
+"32 32 39 1",
+". c #fffbff",
+"# c #b6aeb6",
+"a c #080408",
+"b c #9e9a9e",
+"c c #8e8a8e",
+"d c #386da6",
+"e c #beb6be",
+"f c #000018",
+"g c #a6798e",
+"h c #79869e",
+"i c #a6a2a6",
+"j c #aeaeb6",
+"k c #000808",
+"l c #000010",
+"m c #8e8679",
+"n c #a69ea6",
+"o c #717986",
+"p c #ae9e59",
+"q c #aeb2cf",
+"r c #9696ae",
+"s c #51718e",
+"t c #fff3ff",
+"u c #c7bac7",
+"v c #cfc7cf",
+"w c #eff3f7",
+"x c #696971",
+"y c #ffffff",
+"z c #aea671",
+"A c #ae6161",
+"B c #aea6ae",
+"C c #717571",
+"D c #51a249",
+"E c #867986",
+"F c #bec3cf",
+"G c #6986be",
+"H c #a6a6a6",
+"I c #969696",
+"J c #f7b2ae",
+"K c #5155ff",
+"................................",
+".###############################",
+".#########cddcccbb##############",
+".b#b###cdacddfehcaai##e#e#b#b##e",
+".######kadd#ldmgadaaje####j###e#",
+".ee##jafb#ejdggpogddabb##j###j#b",
+".bbbbdddesdejqerldalaaeeebrbbeee",
+".bbbaddddg######ucaaaddq#rbbre##",
+".###dlllde.####rcddadaabb####b#b",
+".bbdaddgwe######qaaadca##brbb#e#",
+".brabndt.######q#caaadda#rbbb###",
+"tb#dbnv.y...###oogdddaaab#b#nbnb",
+".bA#dqd##y.####ccddddaaabbbrbbbb",
+".bdcadt.y####e###aalldaa#rbbr###",
+".bdcccdh#..####eqclala.abbDEbnub",
+"tbdr##aak#####gcccdda...hodfgnbb",
+".ndpbcaaadd#ecgcsbma....#...Drgb",
+".cdcbndddlaac#jccdd..###..#.drrr",
+"tbdghnallddddhcrpra.#.#..#..fDnb",
+"tbGmohdalddddfzdda.#...#.#...lnb",
+".DDddhoddallacddde#e#########ecq",
+".gcddcscdllldg.#.##.yy.....HH.an",
+".bbbdddolddbhd.##..........mp.lc",
+".nbndfddaddodd.............JJ.lc",
+".hchcddgdadddd......ch#.......an",
+".obcbgfdlddddd................ac",
+".mDmpsgddddKdd................ac",
+".gghcnbBdllald......gh##me....ab",
+".mopcronhmdaad..........y.....ao",
+"whhococchgcgcc.........y.y....ap",
+".Ighhohrccghozgddccccddddccccddc",
+".gzocDocrchosomocgpcopcoscgpcgzr"};
--- /dev/null
+/* XPM */
+static char *file[] = {
+"32 32 157 2",
+".. c #000000",
+".# c #080c08",
+".a c #100400",
+".b c #100c08",
+".c c #101010",
+".d c #181410",
+".e c #181c18",
+".f c #200c00",
+".g c #202020",
+".h c #202028",
+".i c #202428",
+".j c #202430",
+".k c #280c00",
+".l c #281000",
+".m c #281c08",
+".n c #282420",
+".o c #282830",
+".p c #282c30",
+".q c #301000",
+".r c #301400",
+".s c #301408",
+".t c #302820",
+".u c #303038",
+".v c #381400",
+".w c #382010",
+".x c #383840",
+".y c #401808",
+".z c #401c08",
+".A c #402418",
+".B c #402c18",
+".C c #403420",
+".D c #403c28",
+".E c #404040",
+".F c #404448",
+".G c #482008",
+".H c #482818",
+".I c #484850",
+".J c #502008",
+".K c #502810",
+".L c #504c50",
+".M c #505858",
+".N c #582408",
+".O c #582810",
+".P c #582c10",
+".Q c #584838",
+".R c #585868",
+".S c #585c60",
+".T c #602c10",
+".U c #603010",
+".V c #603818",
+".W c #606468",
+".X c #684c30",
+".Y c #686460",
+".Z c #686868",
+".0 c #687070",
+".1 c #703410",
+".2 c #703818",
+".3 c #704028",
+".4 c #705c30",
+".5 c #707470",
+".6 c #784018",
+".7 c #786848",
+".8 c #787470",
+".9 c #787878",
+"#. c #787c78",
+"## c #804420",
+"#a c #808080",
+"#b c #808480",
+"#c c #808888",
+"#d c #884c28",
+"#e c #887048",
+"#f c #887c78",
+"#g c #888888",
+"#h c #888c90",
+"#i c #903020",
+"#j c #905c38",
+"#k c #906438",
+"#l c #909090",
+"#m c #909490",
+"#n c #909498",
+"#o c #909898",
+"#p c #989490",
+"#q c #989898",
+"#r c #989c98",
+"#s c #989ca0",
+"#t c #98a0a0",
+"#u c #a07450",
+"#v c #a07c50",
+"#w c #a08878",
+"#x c #a09c98",
+"#y c #a0a0a0",
+"#z c #a0a4a0",
+"#A c #a0a4a8",
+"#B c #a0a8a8",
+"#C c #a8a4a8",
+"#D c #a8a8a8",
+"#E c #a8aca8",
+"#F c #a8acb0",
+"#G c #a8b0b0",
+"#H c #b09050",
+"#I c #b0b0b0",
+"#J c #b0b4b0",
+"#K c #b0b4b8",
+"#L c #b0b8b8",
+"#M c #b8a490",
+"#N c #b8b8b8",
+"#O c #b8bcb8",
+"#P c #b8bcc0",
+"#Q c #b8c0c0",
+"#R c #c0a058",
+"#S c #c0bcb0",
+"#T c #b2c0dc",
+"#U c #c0c4c0",
+"#V c #c0c4c8",
+"#W c #c0c8c8",
+"#X c #c89060",
+"#Y c #c8ac58",
+"#Z c #c8c8c0",
+"#0 c #c8c8c8",
+"#1 c #c8ccc8",
+"#2 c #c8ccd0",
+"#3 c #d0c0b8",
+"#4 c #d0c8a8",
+"#5 c #d0c8c0",
+"#6 c #d0d0d0",
+"#7 c #d0d0d8",
+"#8 c #d0d4d8",
+"#9 c #d0d8d8",
+"a. c #d8b888",
+"a# c #d8cc58",
+"aa c #d8d8d8",
+"ab c #d8dcd8",
+"ac c #d8dce0",
+"ad c #d8e0e0",
+"ae c #e0b088",
+"af c #e0d0b8",
+"ag c #e0d468",
+"ah c #e0e0e0",
+"ai c #e0e4e8",
+"aj c #e0e8e8",
+"ak c #e8d8b0",
+"al c #e8dc70",
+"am c #e8e8e8",
+"an c #e8ece8",
+"ao c #e8ecf0",
+"ap c #e8f0f0",
+"aq c #f0e460",
+"ar c #f0e4b8",
+"as c #f0f0e8",
+"at c #f0f0f0",
+"au c #f0f0f8",
+"av c #f0f4f8",
+"aw c #f8e8d8",
+"ax c #f8ece0",
+"ay c #f8f4f0",
+"az c #f8f8f8",
+"aA c #f8fcf8",
+"#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#J.8#T#T#T#T#T#T#T#T#f#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#T#T#1#M.z.Z#T#T#T#T#T#T#T#j.k#x#T#T#T#T",
+"#T#T#T#T#T#T#Zad#6.M#T#T#5.4.O.J#f.G#g#T#T#T#T#T.5.W.L#T#T#T#T#T",
+"#T#T#T#T#T#Taa#t#V#b.L.9.l.r.N#eaa#p.A#g#T#T#T#T.L.W#a#T#T#T#T#T",
+"#T#T#T#T#T#T#T#V.R.R.I.E.j.h.h.Saa#8.7.G#r#T#T#Ta#.Q#T#T#T#T#T#T",
+"#T#T#T#T#T#T#U#5.R.I.u.j.j.j.Y#6#P#8#2.X.D#T#T#T#Y.m#T#T#T#T#T#T",
+"#T#T#T#T#5#v#p.x.j.h.j.e#Faj#s#Daa#8#2#2.K.q#Ta..P.0#T#T#T#T#T#T",
+"#T#T#U#S.6.2.W.j.j.o.g#mamajahadaaaa#8#2#C.G.Zag.m#x#T#T#T#T#T#T",
+"anae.6##.6#u#G.o.Zaiatapamajah#Uacacaa#8#V#P#ka#.8#T#T#T#T#T#T#T",
+"acaw##.6#3aAaA.Iavavatapamaj#E#K#zaa#2#2#W#Pag#H#m#T#T#T#T#T#T#T",
+"#T#O#X.6#OaAaAazab#qatapab#F#V#Kaa#m#2#2#0#0#Y.w.y.D#T#T#T#T#T#T",
+"#T#Taw#k.VabaA#c#b#0atah#1#Oahad#I#F#2#2#0#0#H.d.H.q#T#T#T#T#T#T",
+"#T#T#Nay.6.2aAaz#L#q#Uah#I#2#r#q#A#O#B#A#Val.m#y#F.8.l.S#T#T#T#T",
+"#T#T#T#2#k.6#Eazaj#oah#zab#F#V#V#P#m#B#g#Taq.n#L#F#D.q.l#T#T#T#T",
+"#T#T#T#Tazae.2.tavav#C#6#y#F#a#K#g#W#2#qal#Y#z#K#F#E#y.Q.l#m#T#T",
+"#T#T#T#T#Uas.2.Tavav#g#g#yaa#D#g#z#8#r#Qaq#k#N#N#I#F#A#n.q.m#T#T",
+"#T#T#T#T#T#Eae.1.Aaaat#U#z#y#8ai#I#y#T#q#H.m#N#N#N#K#y#s#a.s.t#r",
+"#T#T#T#T#T#Tay#X.1.Fatap.9acaj#K#c#0#r#1#d.I#N#N#N#K#t#s#o.C.k.L",
+"#T#T#T#T#T#T#Taj.2.1#Napao#q#r#.#g#t#2al.d#V#V#V#A#A#t#m.k.k#m#T",
+"#T#T#T#T#T#T#T#J#X.U.tahan#y#z#U#P#t#5aq.M#V#V#V#D#D#g.g.k.##T#T",
+"#T#T#T#T#T#T#T#Tahaf.U.Ganaj.9#oaa#8ae#j#V#T#V#V#F.0.a.f#g#T#T#T",
+"#T#T#T#T#T#T#T#T#Ean.T.P#Uaj#0aiaa#8ae.s#T#Q#N#m.p.....##T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#Taf.3.J.Sahadaa#8.Q.5.i.p.5.p.v.k#g#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#Tanae.T.rahadaa.8.u.F#r#N.F.a.l.##T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#2.3.N.p#8aa#8#2#2#L.g.y.l#.#T#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#4.V.z.Zaa#8#2#2.d.f.l.##T#T#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#Uaw.N.J#N#8#a.c.z.l#g#T#T#T#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#Taa.V.N.pac...s.l.##T#T#T#T#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#T#Tax#u.J.k.G.s.5#T#T#T#T#T#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#T#T#6ar.K.G.l.##T#T#T#T#T#T#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#J#w.r#.#T#T#T#T#T#T#T#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#Taw.p#T#T#T#T#T#T#T#T#T#T#T#T#T#T"};
--- /dev/null
+/* XPM */
+static char *file[] = {
+"32 32 97 2",
+".. c #889988",
+".# c #888899",
+".a c #998899",
+".b c #889999",
+".c c #999999",
+".d c #9999aa",
+".e c #99aa99",
+".f c #aa99aa",
+".g c #99aaaa",
+".h c #aaaaaa",
+".i c #998888",
+".j c #888888",
+".k c #999988",
+".l c #aa9999",
+".m c #cccccc",
+".n c #887788",
+".o c #222222",
+".p c #444444",
+".q c #666666",
+".r c #bbaabb",
+".s c #777777",
+".t c #dddddd",
+".u c #aaaabb",
+".v c #333333",
+".w c #111111",
+".x c #111122",
+".y c #331111",
+".z c #554411",
+".A c #aaaa99",
+".B c #eeddee",
+".C c #778877",
+".D c #666677",
+".E c #776677",
+".F c #221111",
+".G c #443322",
+".H c #555544",
+".I c #ddeedd",
+".J c #777788",
+".K c #556666",
+".L c #778888",
+".M c #555566",
+".N c #555555",
+".O c #bbbbcc",
+".P c #eeeeee",
+".Q c #bbbbbb",
+".R c #443344",
+".S c #110011",
+".T c #111100",
+".U c #772211",
+".V c #663311",
+".W c #442222",
+".X c #332222",
+".Y c #ffffff",
+".Z c #000000",
+".0 c #664433",
+".1 c #ddddcc",
+".2 c #bbaaaa",
+".3 c #ccbbcc",
+".4 c #552200",
+".5 c #884422",
+".6 c #ccdddd",
+".7 c #886655",
+".8 c #776666",
+".9 c #aabbaa",
+"#. c #774444",
+"## c #774433",
+"#a c #bbaa88",
+"#b c #997755",
+"#c c #332211",
+"#d c #332233",
+"#e c #553333",
+"#f c #eeeecc",
+"#g c #ffeeee",
+"#h c #bb8855",
+"#i c #332200",
+"#j c #ccddcc",
+"#k c #333311",
+"#l c #aa9966",
+"#m c #ddbb77",
+"#n c #eedd99",
+"#o c #887777",
+"#p c #ccbbbb",
+"#q c #aaaa66",
+"#r c #eedddd",
+"#s c #8899aa",
+"#t c #8888aa",
+"#u c #667766",
+"#v c #996677",
+"#w c #554444",
+"#x c #aa6633",
+"#y c #884444",
+"#z c #eeeeff",
+"#A c #886666",
+"#B c #bbbbaa",
+"#C c #aabbbb",
+"#D c #776655",
+"#E c #445544",
+"...#...a...a...a...a.b.c.b.c.c.c.c.c.c.c.c.d.e.f.e.d.e.f.e.f.g.h",
+".i.j.a...a...a...a.k.a.k.a.c.c.c.c.c.c.c.l.c.f.c.l.c.f.e.f.e.f.e",
+"...a...#...a.c.m.n.o.p.q.c.c.r.k.i.s.c.d.e.d.e.d.e.f.e.f.e.h.e.h",
+".a...i...a.j.t.h.g.u.v.o.w.x.w.y.z.w.s.j.l.e.l.c.f.e.f.A.f.A.f.A",
+"...a...a...n.B.C.v.h.a.s.D.s.E.o.F.G.F.H...d.e.f.e.f.g.h.g.f.g.h",
+".a...a...a.h.I.J.K.D.L.#.s.M.N.p.o.w.z.F.v.j.f.e.f.e.f.e.f.A.f.A",
+"...a...a.O.P.Q.j.j.L.E.N.R.v.S.T.y.G.U.V.W.X...f.e.h.e.h.g.h.g.h",
+".a...c.m.Y.u.b.E.s.M.p.o.Z.w.o.G.z.V.z.V.0.W.T.k.f.A.f.A.h.A.f.h",
+".r.1.2.P.3.q.E.N.v.T.Z.T.4.0.U.z.V.V.V.z.V.0.V.T.j.f.g.h.g.h.h.h",
+".A.5.z.Y.6.q.v.S.Z.F.z.5.0.V.0.0.z.V.z.G.z.V.z.G.T.s.a.A.f.h.h.h",
+".7.0.U.A.l.v.Z.T.V.5.U.0.V.z.U.V.V.z.V.0.V.z.V.0.V.T.8.h.h.h.h.u",
+".I#..5.V.p.F.z.5.0.V.0.V.0##.z.V.0.V.z.V.z.V.0.V.z.W.T.N.h.h.2.h",
+".J.P#..5.5.5.5.0.V.0.U.z.U.V.V.z.V.z.V.z.V.V.V.z.U.z.V.T.v.u.9.u",
+".E.c.P#..0.0.0.w#a#b.z.V.0.V.z.V.0.V.0.G.0.V.z.V.G.G.z.V#c#d.c.h",
+".j.s.b.t#..5.U.5#e#f#g#h.0.z.V.z.V.z.V.z.V.z.U.z.V.z.V.4.V#i.Z.u",
+".c.C.s.c#j#..0.5.0.F#k#l#m#m.0.V.z.V.0.V.z.V.G.V.z.W.z.G.z.4.W.S",
+".c.c.j.s.r.1.0.z.5.0.W.T.y#h#n#m.5.z.V.z.V.z.V.z.V.4.V.G.4.W.W.G",
+".c.c.j.j#o.Q.1.0.0.0.0.V#c.Z.o#l#n#m.0.G.z.V.z.4.z.G.G.G.z.G.z.G",
+".e.c.c.d...J#p.1.V.z.U.0.5.0.y.Z.y#q#n#m.5.z.U.4.V.z.4.z.z.z.U.z",
+".c.c.l.c.i.C#o.O.9.0.0.V.0.G.0.V#c.S.o#l#n#m.0.G.G.W.z.G.z.V.G.Z",
+".c.d.e.f.e.d.C.n#r.2.U.z.U.z.V.z.V.V.y.Z.y#h#n#m.V.4.W.z.U.Z.Z.p",
+".l.c.f.c.l.c.a.C.n.P.A.V.0.V.z.G.z.V.z.G.o.Z.o#l#s#t.G.W.Z.o.N#u",
+".e.d.e.d.e.f.e.f.C.j#g.A.V.z.V.V.V.z.V.z.V.z.y.T.p.s#v.0#w.q#u.n",
+".l.e.l.c.f.e.f.A.a.C.L.Y.A.V.z.V.z.V.z.G.z.V.z.V.o.x#x#y.E.C.j.k",
+".e.d.e.f.e.f.g.h.g.f.L.C#g.i.U.z.U.z.V.z.V.V.W#c.Z.v.y.4.C.a.b.h",
+".l.c.f.e.f.e.f.e.f.A.a.C.L#z#A.V.z.G.G.W.0.W.Z.Z.p.q.n.C.a.A.f#B",
+".e.f.e.f.e.h.e.h.g.h.b.c.j.k.Y#A.V.V.V.W.W.Z.v.N#u.n.j.a.g.Q#C.Q",
+".f.e.f.A.f.A.f.A.h.A.f.h.c.j.c.Y#D.G.z.W.Z.p.8.C.n.j.f.A.r#B.r.Q",
+".e.f.g.h.g.f.g.h.g.h.h.h.h.d...d.h.W.Z.o#E.E.C.j...f.Y.Y.Y.Y.Y.Y",
+".f.e.f.e.f.A.f.A.f.h.h.h.2.h.c.j.N.W.o.q.E.s.a...f#B.Y.h.h.h.h.N",
+".e.h.e.h.g.h.g.h.h.h.h.u.9.h.e.d.j.q.q.J.j.a.e.r#C.Q.Y.h.h.h.h.N",
+".f.A.f.A.h.A.f.h.h.h.2.h.2.h.2.c.l...j.j.a.e.f#B.r#B.Y.N.N.N.N.N"};
--- /dev/null
+/* XPM */
+static char *file[] = {
+"32 32 10 1",
+". c #ffffff",
+"# c #bebabe",
+"a c #000010",
+"b c #beb6be",
+"c c #aeaaae",
+"d c #aea6ae",
+"e c #c7bac7",
+"f c #000000",
+"g c #ffff00",
+"h c #9e9a9e",
+"................................",
+".###############################",
+".###############################",
+".c#c######c#d####c#d######d#c###",
+".#b#b##b#e#b##b#b#b#eb#beb#bebe#",
+".#####b#d####d#b######d########c",
+".cddc####ccdd####ddcc##b#ddcc###",
+".cddd####dddcb###cdcfff##dccc###",
+".####ccbc####ccc###fgggfc####c#c",
+".cdcd####dcdc####dfggggg#dccc###",
+".cccd####cdcd##ffcggggggfcccc###",
+".c#c#cccffffffffffggggffgfc#cccc",
+".ccccccfggggggggggggggccgfcccccc",
+".cccc###gggggggggggggg##gfccc###",
+".ccdc#c#cfgfgggffcggggggfccccc#c",
+".cccccccccfcffffccggggggfccccccc",
+".cccccccccccccccccffgggfcccccccc",
+".hchcccccchchccfchfffffffchchccc",
+".cccccccccccccccccfffffffccccccc",
+".cccccccffffffffffffffccffcccccc",
+".hhhhccfffffffffffffffccffhhhccc",
+".hhhhcccfffffffffffffffffhhhhccc",
+".ccccchchfffffffccfffffffcccchch",
+".cccchhhhcccchhhhcffffffhcccchhh",
+".hhhhcccchhhhcccchhfffffchhhhccc",
+".hchchhhhchchhhhhhchffhhhchchhhh",
+".hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh",
+".hhhhcccchhhhcccchhhhcccchhhhccc",
+".hhhhchchhhhhhchchhhhchchhhhhhch",
+".hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh",
+".hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh",
+".hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"};
--- /dev/null
+/* XPM */
+static char *file[] = {
+"32 32 18 1",
+". c #ffffff",
+"# c #bebabe",
+"a c #bec3be",
+"b c #000010",
+"c c #aeaaae",
+"d c #9e9a9e",
+"e c #000000",
+"f c #79869e",
+"g c #080408",
+"h c #7992b6",
+"i c #717986",
+"j c #9696ae",
+"k c #bec3cf",
+"l c #beb6be",
+"m c #aeb2cf",
+"n c #867986",
+"o c #c7bac7",
+"p c #aea6ae",
+"................................",
+".####aaaa####aaaa####aaaa####aaa",
+".a##############################",
+".c#c######c#c####cac#a###acac###",
+".###a###a####a###a####aaa#a#a###",
+".a#a#aa#c##aacaa##a###c##aa##a#c",
+".cccc##a#cccc###acccca###cccc#a#",
+".cccc####cccc####cccc####cccca##",
+".a###ccac#a##ccc#a##a#ccc##a#c#c",
+".cccc###acccc####cccc##a#cccc##a",
+".cccca###ceafffa#e#fff##acccd#a#",
+".c#c#cdcc#eeeeecceeegeccd#c#cccc",
+".cccccccccb#ijfccbkjffcccccccccc",
+".cccc####ce#fii##e#fji###cccc###",
+".cccc#c#cce.hiic#e.iihc#cccccc#c",
+".cccccccccelihfeeemiifcccccccccc",
+".cccccccccbkjigeee#nihcccccccccc",
+".dcdcccccce#ihb#ff#hjiccccdcdccc",
+".ccccccccceohieegeonifcccccccccc",
+".ccccccccceegggeeebebecccccccccc",
+".ddddccccdde##fge#afecccpddddccc",
+".ddddccccdddeffccefedccpcddddccc",
+".cccccdcdccceeedceeeccdcdcpccdcd",
+".ccccddddccceggeeegecddddccccddd",
+".ddddcccpdddd#cccddddccccddddccc",
+".dcdcddddcdcddddddcdcddddcdcdddd",
+".ddddddddddddddddddddddddddddddd",
+".ddddccccddddccccddddccccddddccc",
+".ddddcdcddddddcdcddddcdcddddddcd",
+".ddddddddddddddddddddddddddddddd",
+".ddddddddddddddddddddddddddddddd",
+".ddddddddddddddddddddddddddddddd"};
--- /dev/null
+/* XPM */
+static char *file[] = {
+"32 32 104 2",
+".. c #000000",
+".# c #001111",
+".a c #110011",
+".b c #111111",
+".c c #111122",
+".d c #220011",
+".e c #331111",
+".f c #221133",
+".g c #222222",
+".h c #222233",
+".i c #332233",
+".j c #333333",
+".k c #332244",
+".l c #333355",
+".m c #551133",
+".n c #552200",
+".o c #442222",
+".p c #443322",
+".q c #553333",
+".r c #772211",
+".s c #443344",
+".t c #443355",
+".u c #444444",
+".v c #445555",
+".w c #554444",
+".x c #555555",
+".y c #444466",
+".z c #554466",
+".A c #555566",
+".B c #555577",
+".C c #556666",
+".D c #774444",
+".E c #776655",
+".F c #666666",
+".G c #666677",
+".H c #667766",
+".I c #776666",
+".J c #776677",
+".K c #777777",
+".L c #557788",
+".M c #665588",
+".N c #666688",
+".O c #777788",
+".P c #118811",
+".Q c #778877",
+".R c #778888",
+".S c #778899",
+".T c #880011",
+".U c #bb2233",
+".V c #bb6633",
+".W c #996677",
+".X c #cc4422",
+".Y c #dd7733",
+".Z c #886688",
+".0 c #887788",
+".1 c #8877aa",
+".2 c #bb8855",
+".3 c #ddaa77",
+".4 c #888888",
+".5 c #888899",
+".6 c #889988",
+".7 c #889999",
+".8 c #998888",
+".9 c #998899",
+"#. c #999999",
+"## c #8888aa",
+"#a c #8899aa",
+"#b c #9999aa",
+"#c c #9999bb",
+"#d c #99aa99",
+"#e c #99aaaa",
+"#f c #aa9999",
+"#g c #bb9988",
+"#h c #aa88bb",
+"#i c #aa99aa",
+"#j c #aaaaaa",
+"#k c #aaaabb",
+"#l c #aabbaa",
+"#m c #aabbbb",
+"#n c #bbaaaa",
+"#o c #bbaabb",
+"#p c #bbbbbb",
+"#q c #bbbbcc",
+"#r c #bbccbb",
+"#s c #ccbbaa",
+"#t c #ddbbbb",
+"#u c #ccbbcc",
+"#v c #ccbbdd",
+"#w c #ddbbcc",
+"#x c #cccccc",
+"#y c #ccddcc",
+"#z c #ccdddd",
+"#A c #ddcccc",
+"#B c #ddccdd",
+"#C c #ddddcc",
+"#D c #dddddd",
+"#E c #ddeedd",
+"#F c #ddeeee",
+"#G c #eedddd",
+"#H c #eeddee",
+"#I c #eeeeee",
+"#J c #eeeeff",
+"#K c #ffffff",
+"#L c #b2c0dc",
+"#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L",
+"#L#L#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#w#g.e#z#p#L",
+"#L#K#I#F#F#I#J#F#F#J#I#F#F#I#J#F#F#J#I#F#F#F#D#E#K.2.U.n.E.5.M.j",
+"#L#K#F#I#I#F#I#I#I#I#F#I#I#F#I#I#I#I#F#H#D#E#D#I#t.U.T...K.K.G.h",
+"#L#K#I#I....................................#I#H.U.U.d.c.K#..N.f",
+"#L#K#I#F...J.J.L.K.J.0.O.S.0.0.S.R.0.O.O.L.J#K.U.U.n.q.u.6#k.J.g",
+"#L#K#J#F...J.J.O.S.0###a#a#c.9##.5##.0.S.O#H.U.U...e.t.v#m#q.J.c",
+"#L#K#I#I...K.O.0.9.5.9#c#i#b#b.9.9.5.5.0#u#K.U.U.d.j.u.F#p#m.G.c",
+"#L#K#F#I...O.5.9.9#b#k#o#o#k#k#i#h#b.5.9#H.U.T...s.u.F.J#p#l.G.c",
+"#L#K#J#F...O#####c#i#k#q#K#D#i#e#c#c.9#r.V.U...e.u.u.N.L#l#k.N.c",
+"#L#K#I#F...0###a#e#k#K#A.U.U.J#b#c#c#I#E.U.T.w.u.v.G.J.K#l#k.M.c",
+"#L#K#F#I...O.5.9#i#i#C.U.U.U.e.0#h#b#K.X.U...u.u.M.G.K.J#j#j.G.c",
+"#L#K#I#I...O.5.9#c#b.D.3.U.U.T.e.9#x.U.U...q.u.F.J.K.K.J#j#e.A.c",
+"#L#K#I#F...O###a#a#c#q#A.U.U.U.n#b#K.U.U.e.u.A.K.K.J.J.K#e#j.M.b",
+"#L#K#J#F...J.0.S##.9#c#k.U.U.U.U#K.X.T...u.u.J.O.L.J.J.L#e#b.M.b",
+"#L#K#I#I...K.O.0.1.5.5.9.Y.U.U.U.U.U.e...t.x.K.J.J.K.K.J#i#..A.a",
+"#L#K#F#I...K.K.J.0.0.4.0#B.X.U.U.U.U.e.t.z.G.K.J.J.K.K.J#.#..A.b",
+"#L#K#J#F...J.J.L.O.0.0.S#b#t.U.U.U.T.s.u.C.J.J.K.L.J.J.L.7#..B.#",
+"#L#K#I#F...J.J.L.K.J.O.O.O.9.U.U.n.a.u.v.K.J.J.L.K.J.J.K.7#..A.#",
+"#L#K#E#H...K.K.J.J.K.K.J.J.K.....d.o.u.z.J.K.K.J.J.K.K.J.9.6.A.a",
+"#L#K#E#D...K.K.J.J.K.K.J.J.K.G.M.x.u.F.J.J.K.K.J.J.K.K.J.9.4.v.a",
+"#L#K#D#E...J.J.L.K.J.J.K.L.J.J.K.C.M.J.K.L.J.J.L.K.J.J.K.6.4.z..",
+"#L#K#D#z#z#x#x#r#r#x#q#r#m#p#o#l#l#k#k#e#e#b#b.7.7#..z.y.R.4.z..",
+"#L#K#z#D#B#y#x#x#u#r#p#p#o#m#l#n#j#j#j#i#i#.#.#..9.6.P.P.0.Q.u..",
+"#L#K.O.J.J.O.J.J.J.G.G.J.M.G.G.M.M.A.A.M.B.A.A.z.z.x.u.z.z.u.u..",
+"#L.O............................................................",
+"#L#L#L#L#L#L#L#K.H.G.G.H.l.G.0.R.A.u.l.c.h.l.G.H.G.h#L#L#L#L#L#L",
+"#L#L#L#L#L#L#K#D.0.4.Q.0.0.F.u.t.s.l.l.t.A.Q.4.4.8.G#L#L#L#L#L#L",
+"#L#L#L#L#L#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K.G.i#L#L#L#L",
+"#L#L#L#L#L#K#j#j#j#j#j#j#j#j#j#j#j#j#j#j#j#j#j#j#j#j#j..#L#L#L#L",
+"#L#L#L#L#L.M...........................................h#L#L#L#L",
+"#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L"};
--- /dev/null
+/* XPM */
+static char *file[] = {
+"32 32 174 2",
+".. c #3f281f",
+".# c #302820",
+".a c #30282f",
+".b c #303720",
+".c c #3f372f",
+".d c #3f3f2f",
+".e c #203740",
+".f c #2f3f50",
+".g c #3f4f30",
+".h c #3f4740",
+".i c #304750",
+".j c #3f4f50",
+".k c #3f5f40",
+".l c #30575f",
+".m c #3f5f5f",
+".n c #2f4f60",
+".o c #3f5760",
+".p c #305f7f",
+".q c #3f5f70",
+".r c #3f676f",
+".s c #50301f",
+".t c #403f2f",
+".u c #503f20",
+".v c #5f3720",
+".w c #5f3820",
+".x c #603f1f",
+".y c #603820",
+".z c #6f3f20",
+".A c #404730",
+".B c #4f4f30",
+".C c #40582f",
+".D c #504f30",
+".E c #50573f",
+".F c #505f3f",
+".G c #5f573f",
+".H c #406730",
+".I c #4f673f",
+".J c #50673f",
+".K c #5f673f",
+".L c #5f6f3f",
+".M c #70401f",
+".N c #70471f",
+".O c #7f471f",
+".P c #6f472f",
+".Q c #6f4f3f",
+".R c #7f4820",
+".S c #40574f",
+".T c #4f574f",
+".U c #4f5f5f",
+".V c #505f40",
+".W c #5f5740",
+".X c #5f5f4f",
+".Y c #40576f",
+".Z c #4f5f60",
+".0 c #505f6f",
+".1 c #5f6740",
+".2 c #5f704f",
+".3 c #5f7840",
+".4 c #506760",
+".5 c #5f6f6f",
+".6 c #50777f",
+".7 c #605f50",
+".8 c #705f4f",
+".9 c #606740",
+"#. c #6f6f40",
+"## c #60675f",
+"#a c #607740",
+"#b c #607f4f",
+"#c c #60775f",
+"#d c #706750",
+"#e c #706f50",
+"#f c #606f7f",
+"#g c #706f60",
+"#h c #707f60",
+"#i c #707770",
+"#j c #7f7f7f",
+"#k c #406780",
+"#l c #707f90",
+"#m c #6f875f",
+"#n c #708850",
+"#o c #6f977f",
+"#p c #7f8760",
+"#q c #708f7f",
+"#r c #7f9760",
+"#s c #408fb0",
+"#t c #6f8f90",
+"#u c #7f8780",
+"#v c #7087af",
+"#w c #5097cf",
+"#x c #4fa0df",
+"#y c #5fa0cf",
+"#z c #5fafe0",
+"#A c #6098c0",
+"#B c #6fa8e0",
+"#C c #60b0f0",
+"#D c #6fb8ff",
+"#E c #7fb8f0",
+"#F c #7fc0e0",
+"#G c #7fc0f0",
+"#H c #80481f",
+"#I c #8f4f1f",
+"#J c #90501f",
+"#K c #90571f",
+"#L c #9f501f",
+"#M c #804f20",
+"#N c #8f572f",
+"#O c #a0581f",
+"#P c #af581f",
+"#Q c #af5f1f",
+"#R c #b0601f",
+"#S c #af672f",
+"#T c #b06820",
+"#U c #b06f20",
+"#V c #bf703f",
+"#W c #806050",
+"#X c #cf6f1f",
+"#Y c #c07730",
+"#Z c #8f8f6f",
+"#0 c #90976f",
+"#1 c #8f8f80",
+"#2 c #8f8f90",
+"#3 c #809780",
+"#4 c #8f979f",
+"#5 c #90979f",
+"#6 c #9fa890",
+"#7 c #8fa0af",
+"#8 c #8fb0b0",
+"#9 c #90a0af",
+"a. c #a0b89f",
+"a# c #afb0a0",
+"aa c #a0b0b0",
+"ab c #afb8bf",
+"ac c #b0b8bf",
+"ad c #8fa8cf",
+"ae c #8fb8df",
+"af c #9fb0c0",
+"ag c #9fb8d0",
+"ah c #80b0ef",
+"ai c #80b8e0",
+"aj c #a0b8c0",
+"ak c #bfc08f",
+"al c #bfd8bf",
+"am c #80c8ff",
+"an c #8fc8ff",
+"ao c #9fc7ef",
+"ap c #90d0ff",
+"aq c #9fe0ff",
+"ar c #afc0cf",
+"as c #bfc0c0",
+"at c #b0c8d0",
+"au c #afc8e0",
+"av c #afd0ef",
+"aw c #b0d0ef",
+"ax c #bfd0ef",
+"ay c #bfdfff",
+"az c #a0efff",
+"aA c #afe0ff",
+"aB c #b0efff",
+"aC c #c0b0bf",
+"aD c #cfc0bf",
+"aE c #cfc8df",
+"aF c #c0d0c0",
+"aG c #d0d8df",
+"aH c #cfe0e0",
+"aI c #cfe0ff",
+"aJ c #cfe8ff",
+"aK c #cff7ff",
+"aL c #d0e8e0",
+"aM c #e0e8ff",
+"aN c #e0ffff",
+"aO c #eff0f0",
+"aP c #f0f8ff",
+"aQ c #ffffff",
+"aR c #b2c0dc",
+"aRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaR..aRaRaRaRaRaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaR..aRaRaRaRaRaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRaRaRaRaR.T.Z.h.h#jaRaRaRaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRaRaRaRabalayaIau#u#laRaRaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRasaQaOaJamaiaraHajaf#7#uaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRaQaQaKaA#Gaiarataf#8#9#2#faRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRa#aQaLaNanamaiaiajaa#4#7#9#2#i.2aRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaQaQaQaNam#G#Fai#5#Z#m#u#5#j.7.F.CaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaR#4aPaQ#6aNaiaiaxaa#r#r.I.J.F.1.C.I.F.IaRaRaRaRaRaR",
+"aRaRaRaRaRaR#wavaNaPaIaMaoavar#p#n#3.J.J.I.I.C.F.F.FaRaRaRaRaRaR",
+"aRaRaRaRaRaR#FazaqaAaIawaFaE#a#m#3#2.I.J.C.C.F.C.I.F.CaRaRaRaRaR",
+"aRaRaRaRaRaRapazaqaBaoauabaE#1#3#2#j.I.I.H.C.J.F.1.J.BaRaRaRaRaR",
+"aRaRaRaR#H###Gap#D#zaca##h#1.L.K.3.L.I.C.K.F.K.J.F.L.V.d.saRaRaR",
+"aRaR#J#I#X.i#Dam#C#zagac#p#b.L.9.K.L.L.F.1.C.K.8.K.L.9.b.x.vaRaR",
+"aRaR#X#R#I.h#Bah#x#x#t#t#n#..X.X.V.F.V.4.Z.0.F##.K.K#d.c.O.M.zaR",
+"aRaR#R#R#I.O#v#B#w#w.6#a#h.6.6.0.6.7.X.m####.W.X.F.W.c.P.O.O.uaR",
+"aRaR.y#J#Q#R#P#L#V.r.Z.Z.m.Z.m.j.r.m.V.X.G.G.h#N#M.R.R.O.M.x.#aR",
+"aRaRaR.w.R#L#Q#Q#R#T#Y#U#Y#Y#U#U#T#R#R#Q#Q#Q#K#K#J#M.R.M.v..aRaR",
+"aRaRaRaRaRaR.P.z.O.M.O.R.M.M.M.M.M.M.M.M.M.M.R.R.P.z.z.#aRaRaRaR",
+"aRaRaRaRaRaR.Y#W.P.P.w.w.z.M.z.z.z.z.z.z.z.z.w.z.i.q..aRaRaRaRaR",
+"aRaRaRaRaRaRaRaR#k.q.V.1.9.L.9.9.9.V.L.9.W.9.0.q.iaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaR.r.p.r.r.m.4.V.V#.#g.V.V.S.l.r.raRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaR#k.q.q.q.5.X.9.7.W.E.l.n.faRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaR.l.Y.p.q.r.7#d.9.U.m.o.oaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRaRaR.M.M#Q#I.v.z.N.#.#aRaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRaR#Q#P#I#R#I.y.z.N...a.aaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaR#R#X#R#I#Q#J.w.w.x...#.#.#.vaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaR.M#X#R#R#Q...O.z.y.....#.#....aRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaR.M#R#R#R#R.O.M.s.s.s.........saRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaR.w#I#P#R#R#P#H.w.v.s.........saRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaR.w.M#L#P#Q#P#L.M.x.s.s.v.waRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRaRaR.y.M#H#H.R.M.x.v.w.waRaRaRaRaRaRaRaRaRaR"};
--- /dev/null
+/* XPM */
+static char *file[] = {
+"32 32 57 1",
+". c #000000",
+"# c #100010",
+"a c #101000",
+"b c #101010",
+"c c #101020",
+"d c #201010",
+"e c #301010",
+"f c #302010",
+"g c #303010",
+"h c #202020",
+"i c #302020",
+"j c #303030",
+"k c #412020",
+"l c #413020",
+"m c #513030",
+"n c #414530",
+"o c #514530",
+"p c #614530",
+"q c #714530",
+"r c #414541",
+"s c #514541",
+"t c #515541",
+"u c #515551",
+"v c #714541",
+"w c #716551",
+"x c #616561",
+"y c #716571",
+"z c #717571",
+"A c #8e4541",
+"B c #8e6551",
+"C c #9e6551",
+"D c #9e7551",
+"E c #8e6561",
+"F c #9e6571",
+"G c #ae8a61",
+"H c #ae8a71",
+"I c #ae9a61",
+"J c #8e8a8e",
+"K c #9e8a8e",
+"L c #9e8a9e",
+"M c #9e9a8e",
+"N c #ae9a9e",
+"O c #be9a8e",
+"P c #aeaa9e",
+"Q c #beaa8e",
+"R c #aebaae",
+"S c #beaaae",
+"T c #bebaae",
+"U c #cfbaae",
+"V c #dfbabe",
+"W c #cfcfbe",
+"X c #efdf9e",
+"Y c #ffcfae",
+"Z c #dfdfcf",
+"0 c #efdfdf",
+"1 c #efefcf",
+"2 c #b2c0dc",
+"2222222222222222222222222SXYN222",
+"222222222222222222222222ZXSQwO22",
+"2222222222222222222222SXQOGHEv22",
+"2222222222222222222SYQSGGHHHQi22",
+"22222222222222222TZXQHGEHHOQQi22",
+"2222222222221EKYSjuGwEGOOQOQOi22",
+"222222222222WXYQ1BpBGGHOOOOHOi22",
+"222222222SXYOGHBBSiDHGHGGGGHHmy2",
+"22222222YXSQGEwEDUiGGHGGGGGGIsx2",
+"2222TZXUHGEwwBwDDWiDDDDDGGGIQKjL",
+"222SYUOGBBvvBBBBDUiCEDGDGGGHOQvw",
+"TW1ZGDBwvvvBBwBBBYiCCDGDGHIOQQHB",
+"0P.iEwtwwtwwwwwBBZiDDGGGHGHOODvs",
+"1o..1stvvtvtvwwBB1iHDDGGHGDthx22",
+"1pasZpsppvtvvvBBoZ.ZGDGGBvlki222",
+"1saBZosppvtvBwBBoZiEDBvipvBBk222",
+"1odw1sosstvtwBwBDZiDokjsBwGGi222",
+"1pdEZmmopspvBwBBBYisiovwDGGGk222",
+"1shFZmmmoppsvvvviUhpvDCDDCDGk222",
+"1ocKUvommosotwjijWitDEDDDDGGi222",
+"0oiMGHommomjhjosBUiBDCDDGDBshrxx",
+"1siOBHmmlmfcmpswBSiCCDCDBs..rrxJ",
+"1pkNkBsdlmopAvAvBOiCCvs.hrrrxxJJ",
+"0oiThchkmovvvwwBBQiDj..hrrxxJJ22",
+"1oiWomnsstvtvwwBwI..rrrxxJJ22222",
+"1phVspsppvpvvvvpgA.rrxxxJ2222222",
+"1sdWposppvvvk..hrrxxJJ2222222222",
+"1obZospsvpsi.hrrxxxJ222222222222",
+"0o#1ssos..hrrxxxJ222222222222222",
+"Ns.Zvok.hrrrxxJJ2222222222222222",
+"2mm..hrrxxxJ22222222222222222222",
+"2xrrxrxxxJJ222222222222222222222"};