├── .gitignore ├── AUTHORS ├── COPYING ├── ChangeLog ├── INSTALL ├── Makefile.am ├── NEWS ├── README ├── autoclean.sh ├── autogen.sh ├── configure.ac ├── icons ├── Button_close_highlightBackground.bmp ├── Button_close_pushedBackground.bmp ├── Button_colse_normal.bmp ├── Button_max_highlightBackground.bmp ├── Button_max_normalBackground.bmp ├── Button_max_pushedBackground.bmp ├── Button_min_highlightBackground.bmp ├── Button_min_normalBackground.bmp ├── Button_min_pushedBackground.bmp ├── Button_restore_highlightBackground.bmp ├── Button_restore_normal.bmp ├── Button_restore_pushedBackground.bmp ├── ContactMainTabButton1.png ├── ContactMainTabButton2.png ├── GroupMainTabButton1.png ├── GroupMainTabButton2.png ├── MainPanel_Support_DownBackground.bmp ├── MainPanel_Support_NormalBackground.bmp ├── MainPanel_Support_highlightBackground.bmp ├── Makefile.am ├── RecentMainTabButton1.png ├── RecentMainTabButton2.png ├── avatar.gif ├── avatar.png ├── clearscreen.png ├── group.png ├── phone.png ├── qqfaces │ ├── 0.gif │ ├── 1.gif │ ├── 10.gif │ ├── 100.gif │ ├── 101.gif │ ├── 102.gif │ ├── 103.gif │ ├── 104.gif │ ├── 105.gif │ ├── 106.gif │ ├── 107.gif │ ├── 108.gif │ ├── 109.gif │ ├── 11.gif │ ├── 110.gif │ ├── 111.gif │ ├── 112.gif │ ├── 113.gif │ ├── 114.gif │ ├── 115.gif │ ├── 116.gif │ ├── 117.gif │ ├── 118.gif │ ├── 119.gif │ ├── 12.gif │ ├── 120.gif │ ├── 121.gif │ ├── 122.gif │ ├── 123.gif │ ├── 124.gif │ ├── 125.gif │ ├── 126.gif │ ├── 127.gif │ ├── 128.gif │ ├── 129.gif │ ├── 13.gif │ ├── 130.gif │ ├── 131.gif │ ├── 132.gif │ ├── 133.gif │ ├── 134.gif │ ├── 14.gif │ ├── 15.gif │ ├── 16.gif │ ├── 17.gif │ ├── 18.gif │ ├── 19.gif │ ├── 2.gif │ ├── 20.gif │ ├── 21.gif │ ├── 22.gif │ ├── 23.gif │ ├── 24.gif │ ├── 25.gif │ ├── 26.gif │ ├── 27.gif │ ├── 28.gif │ ├── 29.gif │ ├── 3.gif │ ├── 30.gif │ ├── 31.gif │ ├── 32.gif │ ├── 33.gif │ ├── 34.gif │ ├── 35.gif │ ├── 36.gif │ ├── 37.gif │ ├── 38.gif │ ├── 39.gif │ ├── 4.gif │ ├── 40.gif │ ├── 41.gif │ ├── 42.gif │ ├── 43.gif │ ├── 44.gif │ ├── 45.gif │ ├── 46.gif │ ├── 47.gif │ ├── 48.gif │ ├── 49.gif │ ├── 5.gif │ ├── 50.gif │ ├── 51.gif │ ├── 52.gif │ ├── 53.gif │ ├── 54.gif │ ├── 55.gif │ ├── 56.gif │ ├── 57.gif │ ├── 58.gif │ ├── 59.gif │ ├── 6.gif │ ├── 60.gif │ ├── 61.gif │ ├── 62.gif │ ├── 63.gif │ ├── 64.gif │ ├── 65.gif │ ├── 66.gif │ ├── 67.gif │ ├── 68.gif │ ├── 69.gif │ ├── 7.gif │ ├── 70.gif │ ├── 71.gif │ ├── 72.gif │ ├── 73.gif │ ├── 74.gif │ ├── 75.gif │ ├── 76.gif │ ├── 77.gif │ ├── 78.gif │ ├── 79.gif │ ├── 8.gif │ ├── 80.gif │ ├── 81.gif │ ├── 82.gif │ ├── 83.gif │ ├── 84.gif │ ├── 85.gif │ ├── 86.gif │ ├── 87.gif │ ├── 88.gif │ ├── 89.gif │ ├── 9.gif │ ├── 90.gif │ ├── 91.gif │ ├── 92.gif │ ├── 93.gif │ ├── 94.gif │ ├── 95.gif │ ├── 96.gif │ ├── 97.gif │ ├── 98.gif │ ├── 99.gif │ └── Makefile.am ├── selectface.png ├── selectfont.png ├── sendfile.png ├── sendpic.png ├── showhistory.png ├── status │ ├── Makefile.am │ ├── away.png │ ├── busy.png │ ├── callme.png │ ├── downarrow.png │ ├── hidden.png │ ├── offline.png │ ├── online.png │ └── silent.png ├── webqq.png └── webqq_icon.png ├── src ├── Makefile.am ├── cli │ ├── Makefile.am │ └── cli.c ├── gui │ ├── Makefile.am │ ├── buddylist.c │ ├── buddylist.h │ ├── buddytree.c │ ├── buddytree.h │ ├── chattextview.c │ ├── chattextview.h │ ├── chatwidget.c │ ├── chatwidget.h │ ├── chatwindow.c │ ├── chatwindow.h │ ├── loginpanel.c │ ├── loginpanel.h │ ├── main.c │ ├── mainpanel.c │ ├── mainpanel.h │ ├── mainwindow.c │ ├── mainwindow.h │ ├── msgloop.c │ ├── msgloop.h │ ├── splashpanel.c │ ├── splashpanel.h │ ├── statusbutton.c │ ├── statusbutton.h │ ├── tray.c │ └── tray.h ├── include │ ├── Makefile.am │ └── lwqq │ │ ├── Makefile.am │ │ ├── info.h │ │ ├── logger.h │ │ ├── login.h │ │ ├── msg.h │ │ ├── queue.h │ │ ├── smemory.h │ │ └── type.h ├── liblwqq │ ├── Makefile.am │ ├── http.c │ ├── http.h │ ├── http_curl.c │ ├── info.c │ ├── json.c │ ├── json.h │ ├── libghttp │ │ ├── Makefile.am │ │ ├── ghttp.c │ │ ├── ghttp.h │ │ ├── ghttp_constants.h │ │ ├── http_base64.c │ │ ├── http_base64.h │ │ ├── http_date.c │ │ ├── http_date.h │ │ ├── http_global.h │ │ ├── http_hdrs.c │ │ ├── http_hdrs.h │ │ ├── http_req.c │ │ ├── http_req.h │ │ ├── http_resp.c │ │ ├── http_resp.h │ │ ├── http_trans.c │ │ ├── http_trans.h │ │ ├── http_uri.c │ │ └── http_uri.h │ ├── logger.c │ ├── login.c │ ├── md5.c │ ├── md5.h │ ├── msg.c │ ├── smemory.c │ ├── type.c │ ├── unicode.c │ ├── unicode.h │ ├── url.c │ └── url.h └── lwdb │ ├── Makefile.am │ ├── lwdb.c │ ├── lwdb.h │ ├── swsqlite.c │ └── swsqlite.h └── test ├── Makefile.am ├── test_login.c ├── test_lwdb.c └── test_sendmsg.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.lo 3 | *.la 4 | *.in 5 | *.log 6 | *.out 7 | *.files 8 | *.m4 9 | *~ 10 | src/cli/lwqq-cli 11 | test/testlogin 12 | test/testlwdb 13 | test/testsendmsg 14 | config.h 15 | config.status 16 | configure 17 | libtool 18 | stamp-h1 19 | src/gui/lwqq 20 | Makefile 21 | m4/ 22 | autom4te.cache/ 23 | build-aux/ 24 | .deps/ 25 | .libs/ 26 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | lwqq -- A Linux WebQQ Client 2 | ==================================================================== 3 | 4 | This Project is based on kernelhcy's gtkqq project, i rewrite the qq 5 | library to impove its stability 6 | 7 | Current Developers: 8 | ------------------- 9 | mathslinux 10 | xiehuc 11 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/ChangeLog -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS= src test icons 2 | ACLOCAL_AMFLAGS = -I m4 3 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/NEWS -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | #+TITLE: lwqq -- A Linux WebQQ Client 2 | 3 | This Project is based on kernelhcy's gtkqq project, i rewrite the qq 4 | library to impove its stability 5 | 6 | Dependency 7 | ---------- 8 | 9 | - libev (you can `apt-get install libev-dev`) 10 | -------------------------------------------------------------------------------- /autoclean.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | make distclean 2>/dev/null 3 | rm aclocal.m4 autom4te.cache/ config.h.in m4 usr build-aux -rf 2>/dev/null 4 | rm configure 2>/dev/null 5 | (find . -name Makefile.in -exec rm {} \;) 6 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -x 3 | aclocal \ 4 | && autoconf \ 5 | && libtoolize --copy --force --automake \ 6 | && autoreconf --install \ 7 | && ./configure --prefix=/usr --enable-werror 8 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ([2.60]) 5 | AC_INIT([LWQQ], [0.1], [riegamaths@gmail.com], [lwqq], [http://github.com/mathslinux/lwqq]) 6 | AC_CONFIG_AUX_DIR([build-aux]) 7 | AC_CONFIG_MACRO_DIR([m4]) 8 | AM_INIT_AUTOMAKE 9 | AC_CONFIG_HEADERS([config.h]) 10 | 11 | AM_INIT_AUTOMAKE 12 | 13 | # Checks for programs. 14 | AC_PROG_CC 15 | AM_PROG_CC_C_O 16 | AC_PROG_INSTALL 17 | 18 | # libtools 19 | LT_INIT 20 | AC_PROG_LIBTOOL 21 | 22 | # Checks for libraries. 23 | AC_CHECK_LIB([pthread], [pthread_create]) 24 | # Checks for header files. 25 | AC_CHECK_HEADERS([arpa/inet.h fcntl.h netdb.h netinet/in.h stdint.h\ 26 | stdlib.h string.h sys/ioctl.h sys/socket.h unistd.h zlib.h]) 27 | 28 | # Checks for header files. 29 | AC_CHECK_HEADERS([stdlib.h string.h unistd.h]) 30 | 31 | # checks for zlib 32 | PKG_CHECK_MODULES(ZLIB, [zlib >= 1.2], [ 33 | AC_DEFINE(USE_ZLIB, 1, [Use ZLIB]) 34 | AC_SUBST(ZLIB_CFLAGS) 35 | AC_SUBST(ZLIB_LIBS) 36 | ], 37 | ) 38 | 39 | LIBEV_CFLAGS="" 40 | LIBEV_LIBS="" 41 | PKG_CHECK_MODULES([LIBEV], [libev], [], [ 42 | # no pkg-config for libev, searching manually: 43 | AC_CHECK_HEADERS([ev.h],[ 44 | AC_CHECK_LIB([ev], [ev_time], [ 45 | LIBEV_LIBS="-lev" 46 | ],[ 47 | AC_MSG_ERROR([libev not found]) 48 | ] 49 | )],[ 50 | AC_MSG_ERROR([libev not found]) 51 | ] 52 | ) 53 | ]) 54 | 55 | AC_SUBST([LIBEV_CFLAGS]) 56 | AC_SUBST([LIBEV_LIBS]) 57 | 58 | # checks for gtk+3.0 59 | PKG_CHECK_MODULES(GTK, [gtk+-3.0 >= 3.0], [ 60 | AC_DEFINE(USE_GTK, 1, [Use GTK]) 61 | AC_SUBST(GTK_CFLAGS) 62 | AC_SUBST(GTK_LIBS) 63 | ], 64 | ) 65 | # checks for glib2.0 66 | PKG_CHECK_MODULES(GLIB, [glib-2.0 >= 2.30], [ 67 | AC_DEFINE(USE_GLIB, 1, [Use GLIB]) 68 | AC_SUBST(GLIB_CFLAGS) 69 | AC_SUBST(GLIB_LIBS) 70 | ], 71 | ) 72 | 73 | # checks for libsqlite3 74 | PKG_CHECK_MODULES(SQLITE3, [sqlite3 > 3.3], [ 75 | AC_DEFINE(USE_SQLITE3, 1, [Use sqlite3]) 76 | AC_SUBST(SQLITE3_CFLAGS) 77 | AC_SUBST(SQLITE3_LIBS) 78 | ] , [ 79 | echo "" 80 | echo "configure: error: " 81 | echo "libsqlite3 development headers not found." 82 | echo "" 83 | exit -1 84 | ]) 85 | # Checks for typedefs, structures, and compiler characteristics. 86 | AC_C_INLINE 87 | AC_TYPE_SIZE_T 88 | 89 | # Checks for library functions. 90 | AC_FUNC_MALLOC 91 | AC_FUNC_MMAP 92 | # AC_FUNC_STRNLEN 93 | AC_CHECK_FUNCS([bzero gethostbyname memset mkdir select socket strstr strtol]) 94 | 95 | # Set build CFLAGS 96 | CFLAGS="$CFLAGS -fno-strict-aliasing -Wall" 97 | 98 | ###################################################################### 99 | AC_ARG_ENABLE([werror], 100 | [AS_HELP_STRING([--enable-werror],[enable compilation abort on warning (default is no)])], 101 | [if test "$enableval" == "yes"; then 102 | CFLAGS="$CFLAGS -Werror" 103 | fi 104 | ]) 105 | ###################################################################### 106 | 107 | AC_ARG_ENABLE(async-http, 108 | [AS_HELP_STRING([--enable-async-http], [Use asynchronous http translation])], 109 | enable_async_http="$enableval", enable_async_http="no") 110 | 111 | if test "x$enable_async_http" != "xno" ; then 112 | PKG_CHECK_MODULES(CURL, [libcurl], [ 113 | AC_DEFINE(USE_CURL, 1, [Use CURL]) 114 | AC_SUBST(CURL_CFLAGS) 115 | AC_SUBST(CURL_LIBS) 116 | ] , [ 117 | echo "" 118 | echo "configure: error: " 119 | echo "libcurl development headers not found." 120 | echo "" 121 | exit -1 122 | ]) 123 | CFLAGS="$CFLAGS $CURL_CFLAGS -DUSE_ASYNC_HTTP" 124 | LDFLAGS="$LDFLAGS $CURL_LIBS" 125 | else 126 | enable_async_http="no" 127 | fi 128 | AC_CONFIG_FILES([Makefile 129 | src/Makefile 130 | src/include/Makefile 131 | src/include/lwqq/Makefile 132 | src/liblwqq/Makefile 133 | src/liblwqq/libghttp/Makefile 134 | src/lwdb/Makefile 135 | src/gui/Makefile 136 | src/cli/Makefile 137 | test/Makefile 138 | icons/Makefile 139 | icons/qqfaces/Makefile 140 | icons/status/Makefile 141 | ]) 142 | AC_OUTPUT 143 | 144 | echo ============================== OPTIONS ============================== 145 | echo Build CFLAGS: $CFLAGS 146 | echo Build LDFLAGS: $LDFLAGS 147 | echo ===================================================================== 148 | -------------------------------------------------------------------------------- /icons/Button_close_highlightBackground.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/Button_close_highlightBackground.bmp -------------------------------------------------------------------------------- /icons/Button_close_pushedBackground.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/Button_close_pushedBackground.bmp -------------------------------------------------------------------------------- /icons/Button_colse_normal.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/Button_colse_normal.bmp -------------------------------------------------------------------------------- /icons/Button_max_highlightBackground.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/Button_max_highlightBackground.bmp -------------------------------------------------------------------------------- /icons/Button_max_normalBackground.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/Button_max_normalBackground.bmp -------------------------------------------------------------------------------- /icons/Button_max_pushedBackground.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/Button_max_pushedBackground.bmp -------------------------------------------------------------------------------- /icons/Button_min_highlightBackground.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/Button_min_highlightBackground.bmp -------------------------------------------------------------------------------- /icons/Button_min_normalBackground.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/Button_min_normalBackground.bmp -------------------------------------------------------------------------------- /icons/Button_min_pushedBackground.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/Button_min_pushedBackground.bmp -------------------------------------------------------------------------------- /icons/Button_restore_highlightBackground.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/Button_restore_highlightBackground.bmp -------------------------------------------------------------------------------- /icons/Button_restore_normal.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/Button_restore_normal.bmp -------------------------------------------------------------------------------- /icons/Button_restore_pushedBackground.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/Button_restore_pushedBackground.bmp -------------------------------------------------------------------------------- /icons/ContactMainTabButton1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/ContactMainTabButton1.png -------------------------------------------------------------------------------- /icons/ContactMainTabButton2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/ContactMainTabButton2.png -------------------------------------------------------------------------------- /icons/GroupMainTabButton1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/GroupMainTabButton1.png -------------------------------------------------------------------------------- /icons/GroupMainTabButton2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/GroupMainTabButton2.png -------------------------------------------------------------------------------- /icons/MainPanel_Support_DownBackground.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/MainPanel_Support_DownBackground.bmp -------------------------------------------------------------------------------- /icons/MainPanel_Support_NormalBackground.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/MainPanel_Support_NormalBackground.bmp -------------------------------------------------------------------------------- /icons/MainPanel_Support_highlightBackground.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/MainPanel_Support_highlightBackground.bmp -------------------------------------------------------------------------------- /icons/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS=qqfaces status 2 | 3 | iconsdir= ${pkgdatadir}/icons 4 | icons_DATA=\ 5 | Button_close_highlightBackground.bmp\ 6 | Button_close_pushedBackground.bmp\ 7 | Button_colse_normal.bmp\ 8 | Button_max_highlightBackground.bmp\ 9 | Button_max_normalBackground.bmp\ 10 | Button_max_pushedBackground.bmp\ 11 | Button_min_highlightBackground.bmp\ 12 | Button_min_normalBackground.bmp\ 13 | Button_min_pushedBackground.bmp\ 14 | Button_restore_highlightBackground.bmp\ 15 | Button_restore_normal.bmp\ 16 | Button_restore_pushedBackground.bmp\ 17 | MainPanel_Support_DownBackground.bmp\ 18 | MainPanel_Support_highlightBackground.bmp\ 19 | MainPanel_Support_NormalBackground.bmp\ 20 | webqq_icon.png\ 21 | avatar.gif\ 22 | phone.png\ 23 | group.png\ 24 | webqq.png\ 25 | sendfile.png selectfont.png selectface.png sendpic.png\ 26 | showhistory.png clearscreen.png\ 27 | avatar.png\ 28 | ContactMainTabButton1.png ContactMainTabButton2.png\ 29 | GroupMainTabButton1.png GroupMainTabButton2.png\ 30 | RecentMainTabButton1.png RecentMainTabButton2.png 31 | EXTRA_DIST = $(icons_DATA) 32 | -------------------------------------------------------------------------------- /icons/RecentMainTabButton1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/RecentMainTabButton1.png -------------------------------------------------------------------------------- /icons/RecentMainTabButton2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/RecentMainTabButton2.png -------------------------------------------------------------------------------- /icons/avatar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/avatar.gif -------------------------------------------------------------------------------- /icons/avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/avatar.png -------------------------------------------------------------------------------- /icons/clearscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/clearscreen.png -------------------------------------------------------------------------------- /icons/group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/group.png -------------------------------------------------------------------------------- /icons/phone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/phone.png -------------------------------------------------------------------------------- /icons/qqfaces/0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/0.gif -------------------------------------------------------------------------------- /icons/qqfaces/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/1.gif -------------------------------------------------------------------------------- /icons/qqfaces/10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/10.gif -------------------------------------------------------------------------------- /icons/qqfaces/100.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/100.gif -------------------------------------------------------------------------------- /icons/qqfaces/101.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/101.gif -------------------------------------------------------------------------------- /icons/qqfaces/102.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/102.gif -------------------------------------------------------------------------------- /icons/qqfaces/103.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/103.gif -------------------------------------------------------------------------------- /icons/qqfaces/104.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/104.gif -------------------------------------------------------------------------------- /icons/qqfaces/105.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/105.gif -------------------------------------------------------------------------------- /icons/qqfaces/106.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/106.gif -------------------------------------------------------------------------------- /icons/qqfaces/107.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/107.gif -------------------------------------------------------------------------------- /icons/qqfaces/108.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/108.gif -------------------------------------------------------------------------------- /icons/qqfaces/109.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/109.gif -------------------------------------------------------------------------------- /icons/qqfaces/11.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/11.gif -------------------------------------------------------------------------------- /icons/qqfaces/110.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/110.gif -------------------------------------------------------------------------------- /icons/qqfaces/111.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/111.gif -------------------------------------------------------------------------------- /icons/qqfaces/112.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/112.gif -------------------------------------------------------------------------------- /icons/qqfaces/113.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/113.gif -------------------------------------------------------------------------------- /icons/qqfaces/114.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/114.gif -------------------------------------------------------------------------------- /icons/qqfaces/115.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/115.gif -------------------------------------------------------------------------------- /icons/qqfaces/116.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/116.gif -------------------------------------------------------------------------------- /icons/qqfaces/117.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/117.gif -------------------------------------------------------------------------------- /icons/qqfaces/118.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/118.gif -------------------------------------------------------------------------------- /icons/qqfaces/119.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/119.gif -------------------------------------------------------------------------------- /icons/qqfaces/12.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/12.gif -------------------------------------------------------------------------------- /icons/qqfaces/120.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/120.gif -------------------------------------------------------------------------------- /icons/qqfaces/121.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/121.gif -------------------------------------------------------------------------------- /icons/qqfaces/122.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/122.gif -------------------------------------------------------------------------------- /icons/qqfaces/123.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/123.gif -------------------------------------------------------------------------------- /icons/qqfaces/124.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/124.gif -------------------------------------------------------------------------------- /icons/qqfaces/125.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/125.gif -------------------------------------------------------------------------------- /icons/qqfaces/126.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/126.gif -------------------------------------------------------------------------------- /icons/qqfaces/127.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/127.gif -------------------------------------------------------------------------------- /icons/qqfaces/128.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/128.gif -------------------------------------------------------------------------------- /icons/qqfaces/129.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/129.gif -------------------------------------------------------------------------------- /icons/qqfaces/13.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/13.gif -------------------------------------------------------------------------------- /icons/qqfaces/130.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/130.gif -------------------------------------------------------------------------------- /icons/qqfaces/131.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/131.gif -------------------------------------------------------------------------------- /icons/qqfaces/132.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/132.gif -------------------------------------------------------------------------------- /icons/qqfaces/133.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/133.gif -------------------------------------------------------------------------------- /icons/qqfaces/134.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/134.gif -------------------------------------------------------------------------------- /icons/qqfaces/14.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/14.gif -------------------------------------------------------------------------------- /icons/qqfaces/15.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/15.gif -------------------------------------------------------------------------------- /icons/qqfaces/16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/16.gif -------------------------------------------------------------------------------- /icons/qqfaces/17.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/17.gif -------------------------------------------------------------------------------- /icons/qqfaces/18.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/18.gif -------------------------------------------------------------------------------- /icons/qqfaces/19.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/19.gif -------------------------------------------------------------------------------- /icons/qqfaces/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/2.gif -------------------------------------------------------------------------------- /icons/qqfaces/20.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/20.gif -------------------------------------------------------------------------------- /icons/qqfaces/21.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/21.gif -------------------------------------------------------------------------------- /icons/qqfaces/22.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/22.gif -------------------------------------------------------------------------------- /icons/qqfaces/23.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/23.gif -------------------------------------------------------------------------------- /icons/qqfaces/24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/24.gif -------------------------------------------------------------------------------- /icons/qqfaces/25.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/25.gif -------------------------------------------------------------------------------- /icons/qqfaces/26.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/26.gif -------------------------------------------------------------------------------- /icons/qqfaces/27.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/27.gif -------------------------------------------------------------------------------- /icons/qqfaces/28.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/28.gif -------------------------------------------------------------------------------- /icons/qqfaces/29.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/29.gif -------------------------------------------------------------------------------- /icons/qqfaces/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/3.gif -------------------------------------------------------------------------------- /icons/qqfaces/30.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/30.gif -------------------------------------------------------------------------------- /icons/qqfaces/31.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/31.gif -------------------------------------------------------------------------------- /icons/qqfaces/32.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/32.gif -------------------------------------------------------------------------------- /icons/qqfaces/33.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/33.gif -------------------------------------------------------------------------------- /icons/qqfaces/34.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/34.gif -------------------------------------------------------------------------------- /icons/qqfaces/35.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/35.gif -------------------------------------------------------------------------------- /icons/qqfaces/36.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/36.gif -------------------------------------------------------------------------------- /icons/qqfaces/37.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/37.gif -------------------------------------------------------------------------------- /icons/qqfaces/38.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/38.gif -------------------------------------------------------------------------------- /icons/qqfaces/39.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/39.gif -------------------------------------------------------------------------------- /icons/qqfaces/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/4.gif -------------------------------------------------------------------------------- /icons/qqfaces/40.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/40.gif -------------------------------------------------------------------------------- /icons/qqfaces/41.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/41.gif -------------------------------------------------------------------------------- /icons/qqfaces/42.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/42.gif -------------------------------------------------------------------------------- /icons/qqfaces/43.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/43.gif -------------------------------------------------------------------------------- /icons/qqfaces/44.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/44.gif -------------------------------------------------------------------------------- /icons/qqfaces/45.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/45.gif -------------------------------------------------------------------------------- /icons/qqfaces/46.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/46.gif -------------------------------------------------------------------------------- /icons/qqfaces/47.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/47.gif -------------------------------------------------------------------------------- /icons/qqfaces/48.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/48.gif -------------------------------------------------------------------------------- /icons/qqfaces/49.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/49.gif -------------------------------------------------------------------------------- /icons/qqfaces/5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/5.gif -------------------------------------------------------------------------------- /icons/qqfaces/50.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/50.gif -------------------------------------------------------------------------------- /icons/qqfaces/51.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/51.gif -------------------------------------------------------------------------------- /icons/qqfaces/52.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/52.gif -------------------------------------------------------------------------------- /icons/qqfaces/53.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/53.gif -------------------------------------------------------------------------------- /icons/qqfaces/54.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/54.gif -------------------------------------------------------------------------------- /icons/qqfaces/55.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/55.gif -------------------------------------------------------------------------------- /icons/qqfaces/56.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/56.gif -------------------------------------------------------------------------------- /icons/qqfaces/57.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/57.gif -------------------------------------------------------------------------------- /icons/qqfaces/58.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/58.gif -------------------------------------------------------------------------------- /icons/qqfaces/59.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/59.gif -------------------------------------------------------------------------------- /icons/qqfaces/6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/6.gif -------------------------------------------------------------------------------- /icons/qqfaces/60.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/60.gif -------------------------------------------------------------------------------- /icons/qqfaces/61.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/61.gif -------------------------------------------------------------------------------- /icons/qqfaces/62.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/62.gif -------------------------------------------------------------------------------- /icons/qqfaces/63.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/63.gif -------------------------------------------------------------------------------- /icons/qqfaces/64.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/64.gif -------------------------------------------------------------------------------- /icons/qqfaces/65.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/65.gif -------------------------------------------------------------------------------- /icons/qqfaces/66.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/66.gif -------------------------------------------------------------------------------- /icons/qqfaces/67.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/67.gif -------------------------------------------------------------------------------- /icons/qqfaces/68.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/68.gif -------------------------------------------------------------------------------- /icons/qqfaces/69.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/69.gif -------------------------------------------------------------------------------- /icons/qqfaces/7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/7.gif -------------------------------------------------------------------------------- /icons/qqfaces/70.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/70.gif -------------------------------------------------------------------------------- /icons/qqfaces/71.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/71.gif -------------------------------------------------------------------------------- /icons/qqfaces/72.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/72.gif -------------------------------------------------------------------------------- /icons/qqfaces/73.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/73.gif -------------------------------------------------------------------------------- /icons/qqfaces/74.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/74.gif -------------------------------------------------------------------------------- /icons/qqfaces/75.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/75.gif -------------------------------------------------------------------------------- /icons/qqfaces/76.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/76.gif -------------------------------------------------------------------------------- /icons/qqfaces/77.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/77.gif -------------------------------------------------------------------------------- /icons/qqfaces/78.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/78.gif -------------------------------------------------------------------------------- /icons/qqfaces/79.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/79.gif -------------------------------------------------------------------------------- /icons/qqfaces/8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/8.gif -------------------------------------------------------------------------------- /icons/qqfaces/80.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/80.gif -------------------------------------------------------------------------------- /icons/qqfaces/81.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/81.gif -------------------------------------------------------------------------------- /icons/qqfaces/82.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/82.gif -------------------------------------------------------------------------------- /icons/qqfaces/83.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/83.gif -------------------------------------------------------------------------------- /icons/qqfaces/84.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/84.gif -------------------------------------------------------------------------------- /icons/qqfaces/85.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/85.gif -------------------------------------------------------------------------------- /icons/qqfaces/86.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/86.gif -------------------------------------------------------------------------------- /icons/qqfaces/87.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/87.gif -------------------------------------------------------------------------------- /icons/qqfaces/88.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/88.gif -------------------------------------------------------------------------------- /icons/qqfaces/89.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/89.gif -------------------------------------------------------------------------------- /icons/qqfaces/9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/9.gif -------------------------------------------------------------------------------- /icons/qqfaces/90.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/90.gif -------------------------------------------------------------------------------- /icons/qqfaces/91.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/91.gif -------------------------------------------------------------------------------- /icons/qqfaces/92.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/92.gif -------------------------------------------------------------------------------- /icons/qqfaces/93.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/93.gif -------------------------------------------------------------------------------- /icons/qqfaces/94.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/94.gif -------------------------------------------------------------------------------- /icons/qqfaces/95.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/95.gif -------------------------------------------------------------------------------- /icons/qqfaces/96.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/96.gif -------------------------------------------------------------------------------- /icons/qqfaces/97.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/97.gif -------------------------------------------------------------------------------- /icons/qqfaces/98.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/98.gif -------------------------------------------------------------------------------- /icons/qqfaces/99.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/qqfaces/99.gif -------------------------------------------------------------------------------- /icons/qqfaces/Makefile.am: -------------------------------------------------------------------------------- 1 | faceimgdir=${pkgdatadir}/icons/qqfaces 2 | faceimg_DATA=\ 3 | 0.gif 109.gif 118.gif 127.gif 14.gif 23.gif 32.gif\ 4 | 41.gif 50.gif 5.gif 69.gif 78.gif 87.gif 96.gif\ 5 | 100.gif 10.gif 119.gif 128.gif 15.gif 24.gif 33.gif\ 6 | 42.gif 51.gif 60.gif 6.gif 79.gif 88.gif 97.gif\ 7 | 101.gif 110.gif 11.gif 129.gif 16.gif 25.gif 34.gif\ 8 | 43.gif 52.gif 61.gif 70.gif 7.gif 89.gif 98.gif\ 9 | 102.gif 111.gif 120.gif 12.gif 17.gif 26.gif 35.gif\ 10 | 44.gif 53.gif 62.gif 71.gif 80.gif 8.gif 99.gif\ 11 | 103.gif 112.gif 121.gif 130.gif 18.gif 27.gif 36.gif\ 12 | 45.gif 54.gif 63.gif 72.gif 81.gif 90.gif 9.gif\ 13 | 104.gif 113.gif 122.gif 131.gif 19.gif 28.gif 37.gif\ 14 | 46.gif 55.gif 64.gif 73.gif 82.gif 91.gif\ 15 | 105.gif 114.gif 123.gif 132.gif 1.gif 29.gif 38.gif\ 16 | 47.gif 56.gif 65.gif 74.gif 83.gif 92.gif\ 17 | 106.gif 115.gif 124.gif 133.gif 20.gif 2.gif 39.gif\ 18 | 48.gif 57.gif 66.gif 75.gif 84.gif 93.gif\ 19 | 107.gif 116.gif 125.gif 134.gif 21.gif 30.gif 3.gif\ 20 | 49.gif 58.gif 67.gif 76.gif 85.gif 94.gif\ 21 | 108.gif 117.gif 126.gif 13.gif 22.gif 31.gif 40.gif\ 22 | 4.gif 59.gif 68.gif 77.gif 86.gif 95.gif 23 | 24 | EXTRA_DIST = $(faceimg_DATA) 25 | -------------------------------------------------------------------------------- /icons/selectface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/selectface.png -------------------------------------------------------------------------------- /icons/selectfont.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/selectfont.png -------------------------------------------------------------------------------- /icons/sendfile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/sendfile.png -------------------------------------------------------------------------------- /icons/sendpic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/sendpic.png -------------------------------------------------------------------------------- /icons/showhistory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/showhistory.png -------------------------------------------------------------------------------- /icons/status/Makefile.am: -------------------------------------------------------------------------------- 1 | statusimgdir=${pkgdatadir}/icons/status 2 | statusimg_DATA=online.png hidden.png offline.png away.png downarrow.png \ 3 | callme.png busy.png silent.png 4 | EXTRA_DIST=$(statusimg_DATA) 5 | -------------------------------------------------------------------------------- /icons/status/away.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/status/away.png -------------------------------------------------------------------------------- /icons/status/busy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/status/busy.png -------------------------------------------------------------------------------- /icons/status/callme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/status/callme.png -------------------------------------------------------------------------------- /icons/status/downarrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/status/downarrow.png -------------------------------------------------------------------------------- /icons/status/hidden.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/status/hidden.png -------------------------------------------------------------------------------- /icons/status/offline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/status/offline.png -------------------------------------------------------------------------------- /icons/status/online.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/status/online.png -------------------------------------------------------------------------------- /icons/status/silent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/status/silent.png -------------------------------------------------------------------------------- /icons/webqq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/webqq.png -------------------------------------------------------------------------------- /icons/webqq_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mathslinux/lwqq/0083cbc71f56ff09912c8bad4e21d852556d122d/icons/webqq_icon.png -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS=include liblwqq lwdb gui cli 2 | -------------------------------------------------------------------------------- /src/cli/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CFLAGS=-I$(srcdir)/../include/lwqq -I$(srcdir) 2 | 3 | bin_PROGRAMS=lwqq-cli 4 | lwqq_cli_LDADD=../liblwqq/liblwqq.la ../liblwqq/libghttp/libghttp.la \ 5 | $(ZLIB_LIBS) $(LIBEV_LIBS) 6 | lwqq_cli_SOURCES=cli.c 7 | -------------------------------------------------------------------------------- /src/gui/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CFLAGS=-I$(srcdir)/../include/lwqq -I$(srcdir)/../lwdb -I$(srcdir) \ 2 | $(GTK_CFLAGS) -DLWQQ_INSTALL_DIR=\"$(pkgdatadir)\" 3 | 4 | bin_PROGRAMS=lwqq 5 | lwqq_LDADD=../liblwqq/liblwqq.la ../liblwqq/libghttp/libghttp.la \ 6 | ../lwdb/liblwdb.la $(ZLIB_LIBS) $(GTK_LIBS) $(LIBEV_LIBS) 7 | lwqq_SOURCES=main.c mainwindow.c loginpanel.c splashpanel.c mainpanel.c \ 8 | statusbutton.c buddytree.c buddylist.c msgloop.c tray.c \ 9 | chatwindow.c chatwidget.c chattextview.c 10 | -------------------------------------------------------------------------------- /src/gui/buddylist.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file buddylist.h 3 | * @author mathslinux 4 | * @date Sat Jun 23 02:29:09 2012 5 | * 6 | * @brief This file is based on gtkqq written by HuangCongyu 7 | * Inherit from GtkTreeView 8 | * Used to show the groups and recent contancts 9 | * 10 | */ 11 | 12 | #ifndef LWQQ_BUDDYLIST_H 13 | #define LWQQ_BUDDYLIST_H 14 | 15 | #include 16 | 17 | /* FIXME */ 18 | typedef struct QQGMember { 19 | GString *uin; 20 | GString *qqnumber; 21 | GString *nick; 22 | GString *flag; 23 | GString *status; 24 | GString *card; 25 | GString *client_type; 26 | } QQGMember; 27 | 28 | typedef struct QQGroup { 29 | GString *name; 30 | GString *gid; 31 | GString *gnumber; 32 | GString *code; 33 | GString *flag; 34 | GString *owner; 35 | GString *mark; 36 | GString *mask; 37 | GString *option; 38 | GString *createtime; 39 | GString *gclass; 40 | GString *level; 41 | GString *face; 42 | 43 | GString *memo; 44 | GString *fingermemo; 45 | 46 | GPtrArray *members; 47 | } QQGroup; 48 | 49 | #define QQ_TYPE_BUDDY_LIST (qq_buddy_list_get_type()) 50 | #define QQ_BUDDY_LIST(obj) \ 51 | (G_TYPE_CHECK_INSTANCE_CAST((obj), QQ_TYPE_BUDDY_LIST, QQBuddyList)) 52 | #define QQ_IS_BUDDY_LIST(obj) \ 53 | (G_TYPE_CHECK_INSTANCE_TYPE((obj, QQ_TYPE_BUDDY_LIST))) 54 | #define QQ_BUDDY_LIST_CLASS(klass) \ 55 | (G_TYPE_CHECK_CLASS_CAST((klass), QQ_TYPE_BUDDY_LIST, QQBuddyListClass)) 56 | #define QQ_IS_BUDDY_LIST_CLASS(klass) \ 57 | (G_TYPE_CHECK_CLASS_TYPE((klass), QQ_TYPE_BUDDY_LIST)) 58 | #define QQ_BUDDY_LIST_GET_CLASS(obj) \ 59 | (G_TYPE_INSTANCE_GET_CLASS((obj), QQ_TYPE_BUDDY_LIST, QQBuddyListClass)) 60 | 61 | /* List store columns */ 62 | enum{ 63 | BDY_LIST_TYPE = 0, // GDK_TYPE_PIXBUF, client type image 64 | BDY_LIST_IMG, // GDK_TYPE_PIXBUF, face image 65 | BDY_LIST_UIN, // G_TYPE_STRING, buddy uin or group code 66 | BDY_LIST_CLASS, // G_TYPE_INT, buddy or group. 1: buddy, 2:group 67 | // 3: group member 68 | BDY_LIST_NAME, // G_TYPE_STRING, buddy markname or group name 69 | BDY_LIST_LNICK, // G_TYPE_STRING, buddy long nick 70 | BDY_LIST_NUMBER, // G_TYPE_STRING, qq number of the group number 71 | // or group fingermemo 72 | BDY_LIST_COLUMNS // column number 73 | }; 74 | 75 | typedef struct __QQBuddyList QQBuddyList; 76 | typedef struct __QQBuddyListClass QQBuddyListClass; 77 | 78 | struct __QQBuddyList{ 79 | GtkTreeView parent; 80 | }; 81 | 82 | struct __QQBuddyListClass{ 83 | GtkTreeViewClass parent; 84 | }; 85 | 86 | GType qq_buddy_list_get_type(); 87 | GtkWidget * qq_buddy_list_new(); 88 | 89 | // 90 | // Add qq buddy , qq group and qq group member 91 | // 92 | #if 0 93 | void qq_buddy_list_add_buddy(GtkWidget *widget, QQBuddy *bdy); 94 | void qq_buddy_list_add_group(GtkWidget *widget, QQGroup *grp); 95 | void qq_buddy_list_add_group_member(GtkWidget *widget, QQGMember *gm); 96 | #endif 97 | 98 | // 99 | // Add multiple buddies and groups and group members 100 | // 101 | void qq_buddy_list_add_buddies(GtkWidget *widget, GPtrArray *bdies); 102 | void qq_buddy_list_add_groups(GtkWidget *widget, GPtrArray *grps); 103 | void qq_buddy_list_add_group_members(GtkWidget *widget, GPtrArray *gms); 104 | 105 | // 106 | // Update the information of the qq buddy and qq group and member 107 | // 108 | #if 0 109 | void qq_buddy_list_update_buddy_info(GtkWidget *widget, QQBuddy *bdy); 110 | void qq_buddy_list_update_group_info(GtkWidget *widget, QQGroup *grp); 111 | void qq_buddy_list_update_group_member_info(GtkWidget *widget, QQGMember *gm); 112 | #endif 113 | 114 | // 115 | // Update buddies and groups info and group members 116 | // 117 | void qq_buddy_list_update_buddies_info(GtkWidget *widget, GPtrArray *bdies); 118 | void qq_buddy_list_update_groups_info(GtkWidget *widget, GPtrArray *grps); 119 | void qq_buddy_list_update_group_members_info(GtkWidget *widget, GPtrArray *gms); 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /src/gui/buddytree.h: -------------------------------------------------------------------------------- 1 | #ifndef __GTKQQ_BUDDY_TREE_H 2 | #define __GTKQQ_BUDDY_TREE_H 3 | #include 4 | #include "type.h" 5 | 6 | // 7 | // Create the buddy tree view 8 | // 9 | GtkWidget* qq_buddy_tree_new(); 10 | // 11 | // Update the buddy tree view model 12 | // 13 | void qq_buddy_tree_update_model(GtkWidget *tree, LwqqClient *lc); 14 | // 15 | // Update the buddies' face images. 16 | // 17 | void qq_buddy_tree_update_faceimg(GtkWidget *tree, LwqqClient *lc); 18 | // 19 | // Update the online buddies 20 | // 21 | void qq_buddy_tree_update_online_buddies(GtkWidget *tree, LwqqClient *lc); 22 | // 23 | // Update the buddy info 24 | // 25 | void qq_buddy_tree_update_buddy_info(GtkWidget *tree, LwqqClient *lc); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /src/gui/chattextview.h: -------------------------------------------------------------------------------- 1 | #ifndef __QQ_CHAT_TEXT_VIEW_H_ 2 | #define __QQ_CHAT_TEXT_VIEW_H_ 3 | #include 4 | #include "type.h" 5 | 6 | // 7 | // The chat text view 8 | // The chat text view need to show the qq face images and show 9 | // the message like this: 10 | // 11 | // ------------------------------------------ 12 | // | kernel 2010-9-10 12:20:10 | <-- blue 13 | // | hello! | <-- custom color 14 | // | | 15 | // | memory 2010-9-10 12:20:30 | <-- green 16 | // | hello. Need help? | <-- custom color 17 | // | | 18 | // | kernel 2010-9-10 12:21:10 | 19 | // | Yes. Give me more memory. Thanks. | 20 | // | | 21 | // | memory 2010-9-10 12:22:30 | 22 | // | Ok. | 23 | // | | 24 | // | ... ... | 25 | // ------------------------------------------ 26 | // 27 | 28 | #define QQ_CHAT_TEXTVIEW(obj) G_TYPE_CHECK_INSTANCE_CAST(obj\ 29 | , qq_chat_textview_get_type()\ 30 | , QQChatTextview) 31 | #define QQ_CHAT_TEXTVIEWCLASS(c) G_TYPE_CHECK_CLASS_CAST(c\ 32 | , qq_chat_textview_get_type()\ 33 | , QQChatTextviewClass) 34 | #define QQ_IS_CHAT_TEXTVIEW(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj\ 35 | , qq_chat_textview_get_type()) 36 | 37 | typedef struct __QQChatTextview QQChatTextview; 38 | typedef struct __QQChatTextviewClass QQChatTextviewClass; 39 | 40 | struct __QQChatTextview{ 41 | GtkTextView parent; 42 | }; 43 | 44 | struct __QQChatTextviewClass{ 45 | GtkTextViewClass parent; 46 | }; 47 | 48 | GtkWidget* qq_chat_textview_new(); 49 | GType qq_chat_textview_get_type(); 50 | 51 | // 52 | // Clear the view 53 | // 54 | void qq_chat_textview_clear(GtkWidget *widget); 55 | 56 | // 57 | // Add messages 58 | // 59 | void qq_chat_textview_add_recv_message(GtkWidget *widget, LwqqMsgMessage *msg); 60 | void qq_chat_textview_add_send_message(GtkWidget *widget, LwqqMsg *msg); 61 | 62 | // 63 | // Add face or string 64 | // 65 | void qq_chat_textview_add_face(GtkWidget *widget, gint face); 66 | void qq_chat_textview_add_string(GtkWidget *widget, const gchar *str, gint len); 67 | 68 | // 69 | // Set font 70 | // This function will create a new font tag and the new inserted string is setted 71 | // to the new font. Old strings will not change. 72 | // @param name : font name 73 | // @param color : foreground color 74 | // @param size : font size 75 | // @param a, b, c : bold? italic? underline? 76 | // 77 | void qq_chat_textview_set_font(GtkWidget *widget, const gchar *name 78 | , const gchar *color 79 | , gint size 80 | , gint a, gint b, gint c); 81 | 82 | // 83 | // Set the default font the the text view widget 84 | // 85 | void qq_chat_textview_set_default_font(GtkWidget *widget, const gchar *name 86 | , const gchar *color 87 | , gint size 88 | , gint a, gint b, gint c); 89 | 90 | // 91 | // Get the QQMsgContent of the text view. 92 | // Save them in the contents. 93 | // Return the number of the contents 94 | // 95 | gint qq_chat_textview_get_msg_contents(GtkWidget *widget, LwqqMsgMessage *mmsg); 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /src/gui/chatwidget.h: -------------------------------------------------------------------------------- 1 | #ifndef __GTKQQ_CHATWIDGET_H 2 | #define __GTKQQ_CHATWIDGET_H 3 | #include 4 | #include "type.h" 5 | 6 | // 7 | // Chat widget 8 | // Contians: 9 | // message text view, font tool bar, tool bar 10 | // Both the buddy chat window and the group chat window use this widget. 11 | // 12 | // ---------------------------------------------- 13 | // | | 14 | // | | 15 | // | message text view | <-- message text view 16 | // | | 17 | // | | 18 | // ---------------------------------------------- 19 | // | font|v| size|v| |a| |a| |a| |clor| | <-- font tool bar (may hide) 20 | // ---------------------------------------------- 21 | // | |font| |face| ....... |clrscr| | <-- tool bar 22 | // ---------------------------------------------- 23 | // | | 24 | // | input text view | <-- input text view 25 | // | | 26 | // ---------------------------------------------- 27 | // 28 | #define QQ_CHATWIDGET(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, qq_chatwidget_get_type()\ 29 | , QQChatWidget) 30 | #define QQ_CHATWIDGETCLASS(c) G_TYPE_CHECK_CLASS_CAST(c\ 31 | , qq_chatwidget_get_type()\ 32 | , QQChatWidgetClass) 33 | #define QQ_IS_CHATWIDGET(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, qq_chatwidget_get_type()) 34 | 35 | typedef struct __QQChatWidget QQChatWidget; 36 | typedef struct __QQChatWidgetClass QQChatWidgetClass; 37 | 38 | struct __QQChatWidget{ 39 | GtkVBox parent; 40 | 41 | }; 42 | 43 | struct __QQChatWidgetClass{ 44 | GtkVBoxClass parent; 45 | }; 46 | 47 | GtkWidget* qq_chatwidget_new(); 48 | GType qq_chatwidget_get_type(); 49 | 50 | // 51 | // Add messages 52 | // 53 | void qq_chatwidget_add_recv_message(GtkWidget *widget, LwqqMsgMessage *msg); 54 | void qq_chatwidget_add_send_message(GtkWidget *widget, LwqqMsg *msg); 55 | 56 | // 57 | // Get the text view 58 | // 59 | GtkWidget* qq_chatwidget_get_message_textview(GtkWidget *widget); 60 | GtkWidget* qq_chatwidget_get_input_textview(GtkWidget *widget); 61 | 62 | // 63 | // Get the font of font tool bar 64 | // 65 | #if 0 66 | QQMsgContent* qq_chatwidget_get_font(GtkWidget *widget); 67 | #endif 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/gui/chatwindow.h: -------------------------------------------------------------------------------- 1 | #ifndef __GTKQQ_CHATWINDOW_H 2 | #define __GTKQQ_CHATWINDOW_H 3 | #include 4 | #include "msg.h" 5 | 6 | #define QQ_CHATWINDOW(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, qq_chatwindow_get_type()\ 7 | , QQChatWindow) 8 | #define QQ_CHATWINDOWCLASS(c) G_TYPE_CHECK_CLASS_CAST(c\ 9 | , qq_chatwindow_get_type()\ 10 | , QQChatWindowClass) 11 | #define QQ_IS_CHATWINDOW(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, qq_chatwindow_get_type()) 12 | 13 | typedef struct __QQChatWindow QQChatWindow; 14 | typedef struct __QQChatWindowClass QQChatWindowClass; 15 | 16 | struct __QQChatWindow{ 17 | GtkWindow parent; 18 | 19 | }; 20 | 21 | struct __QQChatWindowClass{ 22 | GtkWindowClass parent; 23 | }; 24 | 25 | GtkWidget* qq_chatwindow_new(const gchar *uin); 26 | GType qq_chatwindow_get_type(); 27 | 28 | // 29 | // Add messages 30 | // 31 | void qq_chatwindow_add_recv_message(GtkWidget *widget, LwqqMsgMessage *msg); 32 | void qq_chatwindow_add_send_message(GtkWidget *widget, LwqqMsg *msg); 33 | 34 | #endif /* __GTKQQ_CHATWINDOW_H */ 35 | -------------------------------------------------------------------------------- /src/gui/loginpanel.h: -------------------------------------------------------------------------------- 1 | #ifndef __GTKQQ_LOGINWIN_H 2 | #define __GTKQQ_LOGINWIN_H 3 | #include 4 | #include "lwdb.h" 5 | 6 | #define QQ_LOGINPANEL(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, qq_loginpanel_get_type()\ 7 | , QQLoginPanel) 8 | #define QQ_LOGINPANEL_CLASS(c) G_TYPE_CHECK_CLASS_CAST(c\ 9 | , qq_loginpanel_get_type()\ 10 | , QQLoginPanelClass) 11 | #define QQ_IS_LOGINPANEL(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, qq_loginpanel_get_type()) 12 | 13 | typedef struct _QQLoginPanel QQLoginPanel; 14 | typedef struct _QQLoginPanelClass QQLoginPanelClass; 15 | typedef enum _QQLoginPanelLoginState QQLoginPanelLoginState; 16 | 17 | //the login status 18 | enum _QQLoginPanelLoginState{ 19 | LS_CHECK_VC, //check verify code 20 | LS_LOGIN, //login, get psessionid 21 | LS_GET_MY_INFO, //get information of myself 22 | LS_GET_FRIENDS, //get my friends list. 23 | LS_GET_GROUP_LIST, //get group list. 24 | LS_ONLINE, //get online buddies 25 | LS_RECENT, //get recent connected buddies 26 | LS_SLNICK, //get single long nick 27 | LS_GET_FACEIMG, //get face image 28 | LS_DONE, //finish the login. 29 | LS_ERROR, //error 30 | LS_UNKNOWN //unknown status 31 | }; 32 | 33 | struct _QQLoginPanel{ 34 | GtkVBox parent; 35 | 36 | /*< private >*/ 37 | GtkWidget *uin_label, *uin_entry; 38 | GtkWidget *passwd_label, *passwd_entry; 39 | GtkWidget *rempwcb; /* remember password check button */ 40 | GtkWidget *err_label; /* show error infomation. */ 41 | GtkWidget *login_btn, *status_comb; 42 | #ifdef USE_PROXY 43 | GtkWidget *set_proxy_btn; 44 | #endif /* USE_PROXY */ 45 | 46 | const gchar *uin, *passwd, *status; 47 | gint rempw; 48 | 49 | LwdbGlobalDB *gdb; 50 | GtkWidget *container; 51 | 52 | //used to mark the login state. 53 | QQLoginPanelLoginState login_state; 54 | }; 55 | 56 | struct _QQLoginPanelClass{ 57 | GtkVBoxClass parent; 58 | }; 59 | 60 | /** 61 | * Create a new instance of QQLoginPanel. 62 | * 63 | * @param container : the container which contains this instance. Can be 64 | * set to NULL. 65 | */ 66 | GtkWidget* qq_loginpanel_new(GtkWidget *container); 67 | GType qq_loginpanel_get_type(); 68 | 69 | /** 70 | * Get the inputs 71 | */ 72 | const gchar* qq_loginpanel_get_uin(QQLoginPanel *loginpanel); 73 | const gchar* qq_loginpanel_get_passwd(QQLoginPanel *loginpanel); 74 | const gchar* qq_loginpanel_get_status(QQLoginPanel *loginpanel); 75 | gint qq_loginpanel_get_rempw(QQLoginPanel *loginpanel); 76 | #endif /* __GTKQQ_LOGINWIN_H */ 77 | -------------------------------------------------------------------------------- /src/gui/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "logger.h" 11 | #include "lwdb.h" 12 | 13 | #ifdef USE_GSTREAMER 14 | #include 15 | #endif //USE_GSTREAMER 16 | 17 | /* 18 | * Global 19 | */ 20 | /* Directory where lwqq installed in */ 21 | char *lwqq_install_dir = NULL; 22 | char *lwqq_icons_dir = NULL; 23 | char *lwqq_buddy_status_dir = NULL; 24 | char *lwqq_user_dir = NULL; 25 | QQTray *tray = NULL; 26 | GtkWidget *main_win = NULL; 27 | GHashTable *lwqq_chat_window = NULL; 28 | 29 | // 30 | // The main loop used to get information from the server. 31 | // Such as face images, buddy information. 32 | // 33 | GQQMessageLoop *get_info_loop = NULL; 34 | // 35 | // The main loop used to get qq number and face images from the server. 36 | // Such as face images, buddy information. 37 | // 38 | GQQMessageLoop *get_number_faceimg_loop = NULL; 39 | // 40 | // The main loop used to send messages. 41 | // Such as group messages and buddy messages. 42 | // 43 | GQQMessageLoop *send_loop = NULL; 44 | 45 | 46 | 47 | gboolean debug = FALSE; /* Whether handle debug message */ 48 | 49 | static gboolean _print_version_and_exit(const char *option_name, 50 | const char *value, gpointer data, 51 | GError **error) 52 | { 53 | // g_print("%s %s\n", PACKAGE, VERSION); 54 | exit(EXIT_SUCCESS); 55 | return TRUE; 56 | } 57 | 58 | static GOptionEntry entries[] = 59 | { 60 | {"debug", 'd', 0, G_OPTION_ARG_NONE, &debug, "Open debug mode", NULL}, 61 | {"version", 'v', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, 62 | _print_version_and_exit, "Show the application's version", NULL}, 63 | {NULL} 64 | }; 65 | 66 | static void gui_init() 67 | { 68 | #if !GLIB_CHECK_VERSION(2,32,0) 69 | if (g_thread_get_initialized() == FALSE) { 70 | g_thread_init(NULL); 71 | lwqq_log(LOG_DEBUG, "Init the gthread system\n"); 72 | } 73 | #endif 74 | 75 | get_info_loop = gqq_msgloop_start("Get informain"); 76 | if (get_info_loop == NULL) { 77 | exit(1); 78 | } 79 | 80 | /* initialize lwdb */ 81 | lwdb_init(); 82 | 83 | lwqq_install_dir = g_strdup(LWQQ_INSTALL_DIR); 84 | lwqq_icons_dir = g_strdup_printf("%s/icons", lwqq_install_dir); 85 | lwqq_buddy_status_dir = g_strdup_printf("%s/status", lwqq_icons_dir); 86 | lwqq_user_dir = g_strdup_printf("%s/lwqq", g_get_user_config_dir()); 87 | 88 | /* Hash table for chatwindow */ 89 | lwqq_chat_window = g_hash_table_new_full(g_str_hash, g_str_equal, 90 | g_free, NULL); 91 | } 92 | 93 | static void gui_finalize() 94 | { 95 | lwdb_finalize(); 96 | g_free(lwqq_install_dir); 97 | g_free(lwqq_icons_dir); 98 | g_free(lwqq_buddy_status_dir); 99 | } 100 | 101 | int main(int argc, char **argv) 102 | { 103 | GError *error = NULL; 104 | GOptionContext *context; 105 | context = g_option_context_new(NULL); 106 | g_option_context_add_main_entries(context, entries, NULL); 107 | g_option_context_add_group(context, gtk_get_option_group(TRUE)); 108 | #ifdef USE_GSTREAMER 109 | g_option_context_add_group(context, gst_init_get_option_group()); 110 | #endif 111 | if (!g_option_context_parse(context, &argc, &argv, &error)) { 112 | g_print("option parsing failed: %s\n", error->message); 113 | exit(1); 114 | } 115 | g_option_context_free(context); 116 | 117 | #ifdef USE_GSTREAMER 118 | gst_init(NULL, NULL); 119 | #endif 120 | gtk_init(&argc, &argv); 121 | 122 | gui_init(); 123 | #if 0 124 | log_init(debug); 125 | info = qq_init(NULL); 126 | if(info == NULL){ 127 | return -1; 128 | } 129 | cfg = gqq_config_new(info); 130 | #endif 131 | 132 | send_loop = gqq_msgloop_start("Send"); 133 | if(send_loop == NULL){ 134 | return -1; 135 | } 136 | get_info_loop = gqq_msgloop_start("Get informain"); 137 | if(get_info_loop == NULL){ 138 | return -1; 139 | } 140 | get_number_faceimg_loop = gqq_msgloop_start("Get Number and face images"); 141 | if(get_number_faceimg_loop == NULL){ 142 | return -1; 143 | } 144 | 145 | /* GtkWidget *win = qq_mainwindow_new(); */ 146 | main_win = qq_mainwindow_new(); 147 | tray = qq_tray_new(); 148 | gtk_widget_show_all(main_win); 149 | 150 | gtk_main(); 151 | 152 | g_object_unref(G_OBJECT(tray)); 153 | 154 | gui_finalize(); 155 | #if 0 156 | qq_logout(info, NULL); 157 | #endif 158 | gqq_msgloop_stop(get_info_loop); 159 | gqq_msgloop_stop(send_loop); 160 | 161 | //Save config 162 | #if 0 163 | gqq_config_save(cfg); 164 | qq_finalize(info, NULL); 165 | #endif 166 | return 0; 167 | } 168 | -------------------------------------------------------------------------------- /src/gui/mainpanel.h: -------------------------------------------------------------------------------- 1 | #ifndef __GTKQQ_MAINPANEL_H 2 | #define __GTKQQ_MAINPANEL_H 3 | #include 4 | 5 | #define QQ_MAINPANEL(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, qq_mainpanel_get_type()\ 6 | , QQMainPanel) 7 | #define QQ_MAINPANELCLASS(c) G_TYPE_CHECK_CLASS_CAST(c\ 8 | , qq_mainpanel_get_type()\ 9 | , QQMainPanelClass) 10 | #define QQ_IS_MAINPANEL(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, qq_mainpanel_get_type()) 11 | 12 | typedef struct _QQMainPanel QQMainPanel; 13 | typedef struct _QQMainPanelClass QQMainPanelClass; 14 | 15 | struct _QQMainPanel{ 16 | GtkVBox parent; 17 | 18 | /*< private >*/ 19 | GtkWidget *faceimgframe; //a frame contains gtk image 20 | GtkWidget *faceeventbox; 21 | GdkPixbuf *facepixbuf; 22 | 23 | GtkWidget *status_btn; 24 | GtkWidget *nick; 25 | 26 | GtkWidget *longnick, *longnick_entry; 27 | GtkWidget *longnick_box, *longnick_eventbox; 28 | 29 | GtkWidget *search_entry; 30 | 31 | GtkWidget *buddy_btn, *grp_btn, *recent_btn; 32 | 33 | GtkWidget *notebook; 34 | GtkWidget *buddy_tree; 35 | GtkWidget *group_list; 36 | GtkWidget *recent_list; 37 | 38 | GtkWidget *menubar; 39 | 40 | GtkWidget *container; 41 | }; 42 | 43 | struct _QQMainPanelClass{ 44 | GtkVBoxClass parent; 45 | 46 | /*< private >*/ 47 | GtkWidget *buddy_img[2]; 48 | GtkWidget *grp_img[2]; 49 | GtkWidget *recent_img[2]; 50 | 51 | GdkCursor *hand; 52 | }; 53 | 54 | GType qq_mainpanel_get_type(); 55 | GtkWidget* qq_mainpanel_new(GtkWidget *container); 56 | 57 | // 58 | //Update the information of the panel. 59 | //NOTE: 60 | // This function will create a new model for the tree. 61 | // 62 | void qq_mainpanel_update(QQMainPanel *panel); 63 | // 64 | // Update my information 65 | // 66 | void qq_mainpanel_update_my_info(QQMainPanel *panel); 67 | // 68 | // Update the buddy info 69 | // 70 | void qq_mainpanel_update_buddy_info(QQMainPanel *panel); 71 | void qq_mainpanel_update_buddy_faceimg(QQMainPanel *panel); 72 | void qq_mainpanel_update_online_buddies(QQMainPanel *panel); 73 | 74 | void qq_mainpanel_update_group_info(QQMainPanel *panel); 75 | #endif 76 | -------------------------------------------------------------------------------- /src/gui/mainwindow.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mainwindow.c 3 | * @author mathslinux 4 | * @date Mon May 28 19:45:07 2012 5 | * 6 | * @brief This file is based on gtkqq written by HuangCongyu. 7 | * I rewrite some module for compatible with GTK3 8 | * 9 | * 10 | */ 11 | 12 | #include 13 | #include "mainwindow.h" 14 | #include "loginpanel.h" 15 | #include "splashpanel.h" 16 | #include "mainpanel.h" 17 | #include "type.h" 18 | #include "login.h" 19 | 20 | LwqqClient *lwqq_client = NULL; 21 | 22 | static void qq_mainwindow_init(QQMainWindow *win); 23 | static void qq_mainwindowclass_init(QQMainWindowClass *wc); 24 | 25 | gboolean qq_mainwindow_close(GtkWidget *widget) 26 | { 27 | lwqq_logout(lwqq_client, NULL); 28 | gtk_main_quit(); 29 | /* FIXME */ 30 | #if 0 31 | qq_mainwindow_hide(widget); 32 | #endif 33 | 34 | return TRUE; 35 | } 36 | 37 | GType qq_mainwindow_get_type() 38 | { 39 | static GType t = 0; 40 | if (!t) { 41 | const GTypeInfo info = { 42 | sizeof(QQMainWindowClass), 43 | NULL, /* base_init */ 44 | NULL, /* base_finalize */ 45 | (GClassInitFunc)qq_mainwindowclass_init, 46 | NULL, /* class finalize*/ 47 | NULL, /* class data */ 48 | sizeof(QQMainWindow), 49 | 0, /* n pre allocs */ 50 | (GInstanceInitFunc)qq_mainwindow_init, 51 | 0 52 | }; 53 | 54 | t = g_type_register_static(GTK_TYPE_WINDOW, "QQMainWindow", &info, 0); 55 | } 56 | return t; 57 | } 58 | 59 | /** 60 | * Show the main window. 61 | * 62 | * @param win 63 | */ 64 | void qq_mainwindow_show(GtkWidget *win) 65 | { 66 | QQMainWindow *mainwin = (QQMainWindow *)win; 67 | 68 | mainwin->showed = TRUE; 69 | gtk_widget_show(win); 70 | } 71 | 72 | /** 73 | * Hide the main window 74 | * 75 | * @param win 76 | */ 77 | void qq_mainwindow_hide(GtkWidget *win) 78 | { 79 | QQMainWindow *mainwin = (QQMainWindow *)win; 80 | 81 | mainwin->showed = FALSE; 82 | gtk_widget_hide(win); 83 | } 84 | 85 | /** 86 | * If the window now is shown, hide it, else show it. 87 | * 88 | * @param win 89 | */ 90 | void qq_mainwindow_show_hide(GtkWidget *win) 91 | { 92 | QQMainWindow *mainwin = (QQMainWindow *)win; 93 | 94 | if (TRUE == mainwin->showed) { 95 | qq_mainwindow_hide(win); 96 | } else { 97 | qq_mainwindow_show(win); 98 | } 99 | } 100 | 101 | /** 102 | * Create a new LWQQ window. 103 | * 104 | * 105 | * @return 106 | */ 107 | GtkWidget *qq_mainwindow_new() 108 | { 109 | return GTK_WIDGET(g_object_new(qq_mainwindow_get_type(), "type", 110 | GTK_WINDOW_TOPLEVEL, NULL)); 111 | } 112 | 113 | static void qq_mainwindow_init(QQMainWindow *win) 114 | { 115 | GtkWidget *w = GTK_WIDGET(win); 116 | 117 | /* FIXME: the type of window should be configed by some config file */ 118 | gtk_widget_set_size_request(w, 200, 500); 119 | gtk_window_resize(GTK_WINDOW(w), 250, 550); 120 | 121 | g_signal_connect(w, "delete-event", 122 | G_CALLBACK(qq_mainwindow_close), NULL); 123 | win->showed = FALSE; 124 | 125 | win->login_panel = qq_loginpanel_new(w); 126 | win->splash_panel = qq_splashpanel_new(); 127 | win->main_panel = qq_mainpanel_new(w); 128 | 129 | win->notebook = gtk_notebook_new(); 130 | 131 | gtk_notebook_set_show_tabs(GTK_NOTEBOOK(win->notebook), FALSE); 132 | gtk_notebook_set_show_border(GTK_NOTEBOOK(win->notebook), FALSE); 133 | 134 | gtk_widget_show_all(win->login_panel); 135 | gtk_widget_show_all(win->splash_panel); 136 | gtk_widget_show_all(win->main_panel); 137 | 138 | gtk_notebook_append_page(GTK_NOTEBOOK(win->notebook), 139 | win->login_panel, NULL); 140 | gtk_notebook_append_page(GTK_NOTEBOOK(win->notebook), 141 | win->splash_panel, NULL); 142 | gtk_notebook_append_page(GTK_NOTEBOOK(win->notebook), 143 | win->main_panel, NULL); 144 | 145 | gtk_container_add(GTK_CONTAINER(win), win->notebook); 146 | 147 | gtk_window_set_title(GTK_WINDOW(win), "LWQQ"); 148 | } 149 | 150 | static void qq_mainwindowclass_init(QQMainWindowClass *wc) 151 | { 152 | } 153 | 154 | void qq_mainwindow_show_loginpanel(GtkWidget *win) 155 | { 156 | if (!QQ_IS_MAINWINDOW(win)) { 157 | g_warning("Not a mainwindow!!(%s, %d)", __FILE__, __LINE__); 158 | return; 159 | } 160 | gtk_notebook_set_current_page( 161 | GTK_NOTEBOOK(QQ_MAINWINDOW(win)->notebook), 0); 162 | } 163 | 164 | void qq_mainwindow_show_splashpanel(GtkWidget *win) 165 | { 166 | if (!QQ_IS_MAINWINDOW(win)) { 167 | g_warning("Not a mainwindow!!(%s, %d)", __FILE__, __LINE__); 168 | return; 169 | } 170 | gtk_notebook_set_current_page( 171 | GTK_NOTEBOOK(QQ_MAINWINDOW(win)->notebook), 1); 172 | } 173 | void qq_mainwindow_show_mainpanel(GtkWidget *win) 174 | { 175 | if (!QQ_IS_MAINWINDOW(win)) { 176 | g_warning("Not a mainwindow!!(%s, %d)", __FILE__, __LINE__); 177 | return; 178 | } 179 | gtk_notebook_set_current_page( 180 | GTK_NOTEBOOK(QQ_MAINWINDOW(win)->notebook), 2); 181 | } 182 | -------------------------------------------------------------------------------- /src/gui/mainwindow.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file mainwindow.h 3 | * @author HuangCongyu , 4 | * mathslinux 5 | * @date Mon May 28 19:24:53 2012 6 | * 7 | * @brief This file is based on gtkqq written by HuangCongyu. 8 | * I rewrite some module for compatible with GTK3 9 | * 10 | * 11 | */ 12 | 13 | #ifndef LWQQ_MAINWINDOW_H 14 | #define LWQQ_MAINWINDOW_H 15 | 16 | #include 17 | 18 | #define QQ_MAINWINDOW(obj) \ 19 | G_TYPE_CHECK_INSTANCE_CAST(obj, qq_mainwindow_get_type(), QQMainWindow) 20 | #define QQ_MAINWINDOWCLASS(c) \ 21 | G_TYPE_CHECK_CLASS_CAST(c, qq_mainwindow_get_type(), QQMainWindowClass) 22 | #define QQ_IS_MAINWINDOW(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, qq_mainwindow_get_type()) 23 | 24 | typedef struct __QQMainWindow { 25 | GtkWindow parent; 26 | 27 | GtkWidget *notebook; 28 | 29 | GtkWidget *login_panel; 30 | GtkWidget *main_panel; 31 | GtkWidget *splash_panel; 32 | 33 | gboolean showed; 34 | } QQMainWindow; 35 | 36 | typedef struct __QQMainWindowClass { 37 | GtkWindowClass parent; 38 | } QQMainWindowClass; 39 | 40 | /** 41 | * Create a new LWQQ window. 42 | * 43 | * 44 | * @return 45 | */ 46 | GtkWidget *qq_mainwindow_new(); 47 | 48 | GType qq_mainwindow_get_type(); 49 | 50 | /** 51 | * Show the main window. 52 | * 53 | * @param win 54 | */ 55 | void qq_mainwindow_show(GtkWidget *win); 56 | 57 | /** 58 | * Show the main window. 59 | * 60 | * @param win 61 | */ 62 | void qq_mainwindow_show(GtkWidget *win); 63 | 64 | /** 65 | * Hide the main window 66 | * 67 | * @param win 68 | */ 69 | void qq_mainwindow_hide(GtkWidget *win); 70 | 71 | /** 72 | * If the window now is shown, hide it, else show it. 73 | * 74 | * @param win 75 | */ 76 | void qq_mainwindow_show_hide(GtkWidget *win); 77 | 78 | /** 79 | * If the window now is shown, hide it, else show it 80 | * 81 | * @param win 82 | */ 83 | void qq_mainwindow_show_hide(GtkWidget *win); 84 | 85 | /** 86 | * Show different panels 87 | */ 88 | void qq_mainwindow_show_loginpanel(GtkWidget *win); 89 | void qq_mainwindow_show_splashpanel(GtkWidget *win); 90 | void qq_mainwindow_show_mainpanel(GtkWidget *win); 91 | 92 | #endif /* LWQQ_MAINWINDOW_H */ 93 | -------------------------------------------------------------------------------- /src/gui/msgloop.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file msgloop.c 3 | * @author mathslinux 4 | * @date Wed Jul 4 22:54:16 2012 5 | * @brief This file is written by HuangCongyu. 6 | * Change code style by mathslinux 7 | * 8 | * 9 | */ 10 | 11 | #include 12 | #include "logger.h" 13 | 14 | /* The Invoker type */ 15 | typedef void (*Invoker)(gpointer method, gpointer *pars); 16 | 17 | /** 18 | * GQQClosure 19 | * Contain all the information to invoke a method whoes 20 | * parameters are all gpointer type. 21 | * @param data 22 | * 23 | * @return 24 | */ 25 | typedef struct { 26 | Invoker invoker; 27 | gpointer method; 28 | /// I think that no method's parameters', number will greater ten... 29 | gpointer pars[10]; 30 | } GQQClosure; 31 | 32 | static gpointer thread_main(gpointer data) 33 | { 34 | GQQMessageLoop *ml= (GQQMessageLoop *)data; 35 | char name[256]; 36 | 37 | ml->ctx = g_main_context_new(); 38 | if (ml->ctx == NULL) { 39 | lwqq_log(LOG_ERROR, "Create context for %s loop failed\n", ml->name); 40 | return NULL; 41 | } 42 | 43 | GMainLoop *loop = g_main_loop_new(ml->ctx, TRUE); 44 | if (loop == NULL) { 45 | lwqq_log(LOG_ERROR, "Create %s main loop failed\n", ml->name); 46 | return NULL; 47 | } 48 | ml->loop = loop; 49 | 50 | lwqq_log(LOG_DEBUG, "Start %s main loop ......\n", ml->name); 51 | g_snprintf(name, sizeof(name), "%s", ml->name); 52 | g_main_loop_run(ml->loop); 53 | 54 | lwqq_log(LOG_DEBUG, "%s main loop quit\n", name); 55 | return NULL; 56 | } 57 | 58 | GQQMessageLoop* gqq_msgloop_start(const gchar *name) 59 | { 60 | if (name == NULL) { 61 | name = ""; 62 | } 63 | 64 | GQQMessageLoop *ml = g_slice_new0(GQQMessageLoop); 65 | ml->name = g_strdup(name); 66 | 67 | GError *err = NULL; 68 | #if !GLIB_CHECK_VERSION(2,32,0) 69 | if (g_thread_create(thread_main, ml, FALSE, &err) == NULL) { 70 | #else 71 | if (g_thread_new("main", thread_main, ml) == NULL) { 72 | #endif 73 | lwqq_log(LOG_WARNING, "Create main loop thread failed\n", err->message); 74 | g_error_free(err); 75 | g_free(ml->name); 76 | g_slice_free(GQQMessageLoop, ml); 77 | return NULL; 78 | } 79 | return ml; 80 | } 81 | void gqq_msgloop_stop(GQQMessageLoop *loop) 82 | { 83 | if (loop == NULL) { 84 | return; 85 | } 86 | g_main_context_unref(loop->ctx); 87 | g_main_loop_quit(loop->loop); 88 | g_free(loop->name); 89 | g_slice_free(GQQMessageLoop, loop); 90 | return; 91 | } 92 | 93 | void gqq_method_invoker_1(gpointer method, gpointer *pars) 94 | { 95 | typedef void(*MethodType1)(gpointer); 96 | MethodType1 m = (MethodType1)method; 97 | m(pars[0]); 98 | } 99 | void gqq_method_invoker_2(gpointer method, gpointer *pars) 100 | { 101 | typedef void(*MethodType1)(gpointer, gpointer); 102 | MethodType1 m = (MethodType1)method; 103 | m(pars[0], pars[1]); 104 | } 105 | void gqq_method_invoker_3(gpointer method, gpointer *pars) 106 | { 107 | typedef void(*MethodType1)(gpointer, gpointer, gpointer); 108 | MethodType1 m = (MethodType1)method; 109 | m(pars[0], pars[1], pars[2]); 110 | } 111 | void gqq_method_invoker_4(gpointer method, gpointer *pars) 112 | { 113 | typedef void(*MethodType1)(gpointer, gpointer, gpointer, gpointer); 114 | MethodType1 m = (MethodType1)method; 115 | m(pars[0], pars[1], pars[2], pars[3]); 116 | } 117 | void gqq_method_invoker_5(gpointer method, gpointer *pars) 118 | { 119 | typedef void(*MethodType1)(gpointer, gpointer, gpointer, 120 | gpointer, gpointer); 121 | MethodType1 m = (MethodType1)method; 122 | m(pars[0], pars[1], pars[2], pars[3], pars[4]); 123 | } 124 | 125 | /* The table of the addresses of the invokers */ 126 | static Invoker invokers[] = { 127 | NULL, 128 | gqq_method_invoker_1, 129 | gqq_method_invoker_2, 130 | gqq_method_invoker_3, 131 | gqq_method_invoker_4, 132 | gqq_method_invoker_5, 133 | NULL 134 | }; 135 | 136 | /** 137 | * The callback called in the main loop. 138 | * 139 | * @param data 140 | * 141 | * @return 142 | */ 143 | static gboolean gqq_ctx_callback(gpointer data) 144 | { 145 | GQQClosure *c = (GQQClosure*)data; 146 | /* invoke the method. */ 147 | c->invoker(c->method, c->pars); 148 | /* free the GQQClosure. */ 149 | g_slice_free(GQQClosure, c); 150 | return FALSE; 151 | } 152 | 153 | gint gqq_mainloop_attach(GQQMessageLoop *loop, gpointer method, gint par_num, ...) 154 | { 155 | va_list par; 156 | va_start(par, par_num); 157 | GQQClosure *c = g_slice_new0(GQQClosure); 158 | c->method = method; 159 | c->invoker = invokers[par_num]; 160 | gpointer p; 161 | gint i; 162 | for(i = 0; i < par_num; ++i){ 163 | p = va_arg(par, gpointer); 164 | c->pars[i] = p; 165 | } 166 | va_end(par); 167 | 168 | GSource *src = g_idle_source_new(); 169 | g_source_set_callback(src, gqq_ctx_callback, c, NULL); 170 | g_source_attach(src, loop->ctx); 171 | g_source_unref(src); 172 | return 0; 173 | } 174 | -------------------------------------------------------------------------------- /src/gui/msgloop.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file msgloop.h 3 | * @author mathslinux 4 | * @date Wed Jul 4 22:54:16 2012 5 | * 6 | * @brief This file is written by HuangCongyu. 7 | * Change code style by mathslinux 8 | * 9 | * 10 | */ 11 | 12 | #ifndef __GQQ_MSGLOOP_H_ 13 | #define __GQQ_MSGLOOP_H_ 14 | 15 | #include 16 | #include 17 | 18 | /** 19 | * The wrapper of the main loop. 20 | */ 21 | typedef struct __GQQMessageLoop { 22 | GMainLoop *loop; 23 | GMainContext *ctx; 24 | gchar *name; 25 | } GQQMessageLoop; 26 | 27 | /** 28 | * Start a new main loop. 29 | * The new main loop will run in a new thread. 30 | * 31 | * @param name 32 | * 33 | * @return 34 | */ 35 | GQQMessageLoop* gqq_msgloop_start(const gchar *name); 36 | 37 | void gqq_msgloop_stop(GQQMessageLoop *loop); 38 | 39 | /** 40 | * Invoke the method in the main loop `loop`. 41 | * NOTE: The types of the parameters of the method must be pointer. 42 | * 43 | * @param loop 44 | * @param method : the address of the method which will be called in the 45 | * message loop. 46 | * @param par_num the number of the parameter of the method. <= 5 47 | * 48 | * @return 49 | */ 50 | gint gqq_mainloop_attach(GQQMessageLoop* loop, gpointer method, gint par_num, ...); 51 | 52 | #endif /* __GQQ_MSGLOOP_H_ */ 53 | -------------------------------------------------------------------------------- /src/gui/splashpanel.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "type.h" 3 | 4 | #ifdef HAVE_CONFIG_H 5 | #include 6 | #endif 7 | 8 | extern LwqqClient *lwqq_client; 9 | extern char *lwqq_install_dir; 10 | extern char *lwqq_icons_dir; 11 | extern char *lwqq_buddy_status_dir; 12 | extern GtkWidget *main_win; 13 | 14 | static void qq_splashpanelclass_init(QQSplashPanelClass *c); 15 | static void qq_splashpanel_init(QQSplashPanel *obj); 16 | static void qq_splashpanel_destroy(GtkWidget *obj); 17 | 18 | GtkWidget *qq_splashpanel_new() 19 | { 20 | QQSplashPanel *panel = g_object_new(qq_splashpanel_get_type(), NULL); 21 | return GTK_WIDGET(panel); 22 | } 23 | 24 | GType qq_splashpanel_get_type() 25 | { 26 | static GType t = 0; 27 | if(!t){ 28 | static const GTypeInfo info = 29 | { 30 | sizeof(QQSplashPanelClass), 31 | NULL, 32 | NULL, 33 | (GClassInitFunc)qq_splashpanelclass_init, 34 | NULL, 35 | NULL, 36 | sizeof(QQSplashPanel), 37 | 0, 38 | (GInstanceInitFunc)qq_splashpanel_init, 39 | NULL 40 | }; 41 | t = g_type_register_static(GTK_TYPE_VBOX, "QQSplashPanel" 42 | , &info, 0); 43 | } 44 | return t; 45 | 46 | } 47 | 48 | static void qq_splashpanelclass_init(QQSplashPanelClass *c) 49 | { 50 | GtkWidgetClass *cl = GTK_WIDGET_CLASS(c); 51 | cl -> destroy = qq_splashpanel_destroy; 52 | } 53 | 54 | /* 55 | * Let the progress bar shake. 56 | */ 57 | static gboolean progress_bar_timeout_func(gpointer data) 58 | { 59 | gtk_progress_bar_pulse(GTK_PROGRESS_BAR(data)); 60 | return TRUE; 61 | } 62 | 63 | static void qq_splashpanel_init(QQSplashPanel *obj) 64 | { 65 | gchar img[256]; 66 | g_snprintf(img, sizeof(img), "%s/webqq_icon.png", lwqq_icons_dir); 67 | GtkWidget *logo = gtk_image_new_from_file(img); 68 | gtk_widget_set_size_request(logo, -1, 250); 69 | gtk_box_pack_start(GTK_BOX(obj), logo, FALSE, FALSE, 0); 70 | 71 | GtkWidget *probar = gtk_progress_bar_new(); 72 | gtk_widget_set_size_request(probar, 200, 50); 73 | gtk_progress_bar_set_text(GTK_PROGRESS_BAR(probar), "Login..."); 74 | #ifdef USE_GTK3 75 | gtk_progress_bar_set_show_text(GTK_PROGRESS_BAR(probar), TRUE); 76 | #endif /* USE_GTK3 */ 77 | 78 | g_timeout_add(100, progress_bar_timeout_func, probar); 79 | 80 | GtkWidget *box = NULL; 81 | box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); 82 | gtk_box_pack_start(GTK_BOX(box), probar, TRUE, FALSE, 0); 83 | gtk_box_pack_start(GTK_BOX(obj), box, FALSE, FALSE, 50); 84 | } 85 | static void qq_splashpanel_destroy(GtkWidget *obj) 86 | { 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/gui/splashpanel.h: -------------------------------------------------------------------------------- 1 | #ifndef __GTKQQ_SPLASHPANEL_H 2 | #define __GTKQQ_SPLASHPANEL_H 3 | #include 4 | 5 | #define QQ_SPLASHPANEL(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, qq_splashpanel_get_type(),\ 6 | QQSplashPanel) 7 | #define QQ_SPLASHPANEL_CLASS(c) G_TYPE_CHECK_CLASS_CAST(c,\ 8 | qq_splashpanel_get_type(),\ 9 | QQSplashPanelClass) 10 | #define QQ_IS_SPLASHPANEL(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, qq_splashPanel_get_type()) 11 | 12 | typedef struct _QQSplashPanel QQSplashPanel; 13 | typedef struct _QQSplashPanelClass QQSplashPanelClass; 14 | 15 | struct _QQSplashPanel{ 16 | GtkVBox parent; 17 | }; 18 | 19 | struct _QQSplashPanelClass{ 20 | GtkVBoxClass parent; 21 | }; 22 | 23 | GtkWidget *qq_splashpanel_new(); 24 | GType qq_splashpanel_get_type(); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/gui/statusbutton.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file statusbutton.c 3 | * @author Dunrong Huang 4 | * @date Wed Jun 20 19:20:37 2012 5 | * 6 | * @brief This file is based on gtkqq written by HuangCongyu 7 | * 8 | * 9 | */ 10 | 11 | #include "statusbutton.h" 12 | 13 | extern char *lwqq_install_dir; 14 | extern char *lwqq_icons_dir; 15 | extern char *lwqq_buddy_status_dir; 16 | 17 | static const gchar *status_label[] = { 18 | "online", "hidden", "away", "offline", "callme", "busy", "silent", NULL}; 19 | 20 | static QQStatusButtonClass *this_class = NULL; 21 | 22 | static void qq_statusbutton_init(QQStatusButton *btn); 23 | static void qq_statusbuttonclass_init(QQStatusButtonClass *c); 24 | 25 | static gboolean expose_event_cb(GtkWidget *widget, 26 | GdkEventExpose *event, gpointer data); 27 | static void change_img_cb(GtkComboBox *w, gpointer data); 28 | 29 | static gboolean enter_event_cb(GtkWidget *w, GdkEvent *event, gpointer data); 30 | static gboolean leave_event_cb(GtkWidget *w, GdkEvent *event, gpointer data); 31 | 32 | GType qq_statusbutton_get_type() 33 | { 34 | static GType t = 0; 35 | if (!t) { 36 | static const GTypeInfo info = { 37 | sizeof(QQStatusButtonClass), 38 | NULL, 39 | NULL, 40 | (GClassInitFunc)qq_statusbuttonclass_init, 41 | NULL, 42 | NULL, 43 | sizeof(QQStatusButton), 44 | 0, 45 | (GInstanceInitFunc)qq_statusbutton_init, 46 | NULL 47 | }; 48 | t = g_type_register_static(GTK_TYPE_COMBO_BOX, "QQStatusButton", &info, 0); 49 | } 50 | return t; 51 | } 52 | 53 | /* 54 | * Create the treemode for the status combo box. 55 | */ 56 | static GtkTreeModel* create_model() 57 | { 58 | GtkTreeIter iter; 59 | GtkListStore *store; 60 | gint i; 61 | 62 | store = gtk_list_store_new(2, GDK_TYPE_PIXBUF, G_TYPE_STRING); 63 | for (i = 0; i < STATUS_NUM; i++) { 64 | gtk_list_store_append(store, &iter); 65 | gtk_list_store_set(store, &iter, 0, this_class->pb[i], 1, 66 | status_label[i], -1); 67 | } 68 | return GTK_TREE_MODEL(store); 69 | } 70 | 71 | GtkWidget* qq_statusbutton_new() 72 | { 73 | gpointer btn = g_object_new(QQ_TYPE_STATUSBUTTON, NULL); 74 | return GTK_WIDGET(btn); 75 | } 76 | 77 | static void qq_statusbutton_init(QQStatusButton *btn) 78 | { 79 | gtk_widget_set_size_request(GTK_WIDGET(btn), 30, 25); 80 | gtk_combo_box_set_model(GTK_COMBO_BOX(btn), create_model()); 81 | GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new(); 82 | gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(btn), renderer, FALSE); 83 | gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(btn), renderer, 84 | "pixbuf", 0, NULL); 85 | renderer = gtk_cell_renderer_text_new(); 86 | gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(btn), renderer, FALSE); 87 | gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(btn), renderer, 88 | "text", 1, NULL); 89 | 90 | GdkEventMask event_mask = 0; 91 | event_mask = gtk_widget_get_events(GTK_WIDGET(btn)); 92 | event_mask |= GDK_POINTER_MOTION_MASK; 93 | event_mask |= GDK_ENTER_NOTIFY_MASK; 94 | event_mask |= GDK_LEAVE_NOTIFY_MASK; 95 | gtk_widget_set_events(GTK_WIDGET(btn), event_mask); 96 | g_signal_connect(GTK_WIDGET(btn), "draw", 97 | G_CALLBACK(expose_event_cb), NULL); 98 | g_signal_connect(GTK_WIDGET(btn), "changed", 99 | G_CALLBACK(change_img_cb), NULL); 100 | g_signal_connect(GTK_WIDGET(btn), "enter-notify-event", 101 | G_CALLBACK(enter_event_cb), NULL); 102 | g_signal_connect(GTK_WIDGET(btn), "leave-notify-event", 103 | G_CALLBACK(leave_event_cb), NULL); 104 | 105 | btn->status = STATUS_ONLINE; 106 | gtk_combo_box_set_active(GTK_COMBO_BOX(btn), STATUS_ONLINE); 107 | } 108 | 109 | static void qq_statusbuttonclass_init(QQStatusButtonClass *c) 110 | { 111 | char img[512]; 112 | /* FIXME */ 113 | #define QQ_STATUSBUTTON_INIT_MACRO(status, name, w, h, b) { \ 114 | g_snprintf(img, sizeof(img), "%s/%s", lwqq_buddy_status_dir, name); \ 115 | c->pb[status] = gdk_pixbuf_new_from_file_at_scale(img, w, h, b, NULL); \ 116 | } 117 | 118 | QQ_STATUSBUTTON_INIT_MACRO(STATUS_ONLINE, "online.png", 12, 12, TRUE); 119 | QQ_STATUSBUTTON_INIT_MACRO(STATUS_HIDDEN, "hidden.png", 12, 12, TRUE); 120 | QQ_STATUSBUTTON_INIT_MACRO(STATUS_OFFLINE, "offline.png", 12, 12, TRUE); 121 | QQ_STATUSBUTTON_INIT_MACRO(STATUS_AWAY, "away.png", 12, 12, TRUE); 122 | QQ_STATUSBUTTON_INIT_MACRO(STATUS_CALLME, "callme.png", 12, 12, TRUE); 123 | QQ_STATUSBUTTON_INIT_MACRO(STATUS_BUSY, "busy.png", 12, 12, TRUE); 124 | QQ_STATUSBUTTON_INIT_MACRO(STATUS_SILENT, "silent.png", 12, 12, TRUE); 125 | 126 | g_snprintf(img, sizeof(img), "%s/downarrow.png", lwqq_buddy_status_dir); 127 | c->arrow = gdk_pixbuf_new_from_file_at_scale(img, 10, 7, TRUE, NULL); 128 | #undef QQ_STATUSBUTTON_INIT_MACRO 129 | c->hand_cursor = gdk_cursor_new(GDK_HAND1); 130 | this_class = c; 131 | } 132 | 133 | /* 134 | * 135 | */ 136 | static gboolean expose_event_cb(GtkWidget *widget 137 | , GdkEventExpose *event, gpointer data) 138 | { 139 | cairo_t *ct = gdk_cairo_create(gtk_widget_get_window(widget)); 140 | GdkPixbuf *pb = this_class->pb[QQ_STATUSBUTTON(widget)->status]; 141 | gint pbw, pbh, arroww, arrowh, gap = 5; 142 | pbw = gdk_pixbuf_get_width(pb); 143 | pbh = gdk_pixbuf_get_height(pb); 144 | arroww = gdk_pixbuf_get_width(this_class->arrow); 145 | arrowh = gdk_pixbuf_get_height(this_class->arrow); 146 | GtkAllocation alloc; 147 | gtk_widget_get_allocation(widget, &alloc); 148 | 149 | gint alignx, aligny; 150 | alignx = (alloc.width - pbw - arroww - gap) / 2; 151 | aligny = (alloc.height - pbh) / 2; 152 | 153 | //maybe they are - 154 | alignx = (alignx > 0 ? alignx : 0); 155 | aligny = (aligny > 0 ? aligny : 0); 156 | 157 | gdk_cairo_set_source_pixbuf(ct, pb, alloc.x + alignx, alloc.y + aligny); 158 | cairo_paint(ct); 159 | 160 | //parint the down arrow 161 | aligny = (alloc.height - arrowh) / 2; 162 | aligny = (aligny > 0 ? aligny : 0); 163 | gdk_cairo_set_source_pixbuf(ct, this_class->arrow, 164 | alloc.x + alignx + pbw + gap, alloc.y + aligny); 165 | cairo_paint(ct); 166 | cairo_destroy(ct); 167 | 168 | /* 169 | * Stop the signal transferring. 170 | * Or not, the normal UI will cover the image. 171 | */ 172 | return TRUE; 173 | } 174 | 175 | const gchar* qq_statusbutton_get_status_string(GtkWidget *btn) 176 | { 177 | if (btn == NULL) { 178 | return NULL; 179 | } 180 | 181 | gint idx = gtk_combo_box_get_active(GTK_COMBO_BOX(btn)); 182 | return status_label[idx]; 183 | } 184 | 185 | QQStatusButtonStatus qq_statusbutton_get_status(GtkWidget *btn) 186 | { 187 | if (btn == NULL) { 188 | return STATUS_NUM; 189 | } 190 | 191 | gint idx = gtk_combo_box_get_active(GTK_COMBO_BOX(btn)); 192 | return idx; 193 | } 194 | 195 | void qq_statusbutton_set_status_string(GtkWidget *btn 196 | , const gchar *status) 197 | { 198 | if (btn == NULL || status == NULL) { 199 | return; 200 | } 201 | gint i; 202 | for (i = 0; i < STATUS_NUM; ++i) { 203 | if (g_strcmp0(status_label[i], status) == 0) { 204 | break; 205 | } 206 | } 207 | if (i < STATUS_NUM) { 208 | gtk_combo_box_set_active(GTK_COMBO_BOX(btn), i); 209 | } 210 | } 211 | 212 | void qq_statusbutton_set_status(GtkWidget *btn 213 | , QQStatusButtonStatus status) 214 | { 215 | if (btn == NULL || status >= STATUS_NUM|| status < 0) { 216 | return; 217 | } 218 | 219 | gtk_combo_box_set_active(GTK_COMBO_BOX(btn), status); 220 | } 221 | /* 222 | * `changed` signal handler 223 | * Change the shown image 224 | */ 225 | static void change_img_cb(GtkComboBox *w, gpointer data) 226 | { 227 | QQStatusButton *btn = QQ_STATUSBUTTON(w); 228 | btn->status = gtk_combo_box_get_active(w); 229 | 230 | //Maybe this combo box has not been realized. 231 | //So, we must test. If not be realized, just return. 232 | if (gtk_widget_get_window(GTK_WIDGET(w)) == NULL) { 233 | return; 234 | } 235 | 236 | expose_event_cb(GTK_WIDGET(w), NULL, NULL); 237 | } 238 | 239 | static gboolean enter_event_cb(GtkWidget *w, GdkEvent *event, gpointer data) 240 | { 241 | GdkWindow *win = gtk_widget_get_window(w); 242 | g_debug("enter status button."); 243 | if (win != NULL) { 244 | //Set to hand1 cursor. 245 | gdk_window_set_cursor(win, this_class->hand_cursor); 246 | } 247 | return FALSE; 248 | } 249 | static gboolean leave_event_cb(GtkWidget *w, GdkEvent *event, gpointer data) 250 | { 251 | GdkWindow *win = gtk_widget_get_window(w); 252 | g_debug("leave status button."); 253 | if (win != NULL) { 254 | //Set to default cursor. 255 | gdk_window_set_cursor(win, NULL); 256 | } 257 | return FALSE; 258 | } 259 | 260 | -------------------------------------------------------------------------------- /src/gui/statusbutton.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file statusbutton.c 3 | * @author Dunrong Huang 4 | * @date Wed Jun 20 19:20:37 2012 5 | * 6 | * @brief This file is based on gtkqq written by HuangCongyu 7 | * 8 | * 9 | */ 10 | 11 | #ifndef __LWQQ_STATUS_BUTTON 12 | #define __LWQQ_STATUS_BUTTON 13 | 14 | #include 15 | 16 | /* 17 | * QQ status button. 18 | * Show and change the status. 19 | */ 20 | #define QQ_STATUSBUTTON(obj) \ 21 | G_TYPE_CHECK_INSTANCE_CAST(obj, qq_statusbutton_get_type(), QQStatusButton) 22 | #define QQ_STATUSBUTTONCLASS(c) \ 23 | G_TYPE_CHECK_CLASS_CAST(c, qq_statusbutton_get_type(), QQStatusButtonClass) 24 | #define QQ_IS_STATUSBUTTON(obj) \ 25 | G_TYPE_CHECK_INSTANCE_TYPE(obj, qq_statusbutton_get_type()) 26 | #define QQ_TYPE_STATUSBUTTON qq_statusbutton_get_type() 27 | 28 | typedef struct _QQStatusButton QQStatusButton; 29 | typedef struct _QQStatusButtonClass QQStatusButtonClass; 30 | 31 | typedef enum _QQStatusButtonStatus QQStatusButtonStatus; 32 | 33 | enum _QQStatusButtonStatus { 34 | STATUS_ONLINE = 0, 35 | STATUS_HIDDEN, 36 | STATUS_AWAY, 37 | STATUS_OFFLINE, 38 | STATUS_CALLME, 39 | STATUS_BUSY, 40 | STATUS_SILENT, 41 | STATUS_NUM 42 | }; 43 | 44 | struct _QQStatusButton { 45 | GtkComboBox parent; 46 | QQStatusButtonStatus status; 47 | 48 | /*< private >*/ 49 | GtkWidget *popmenu; 50 | }; 51 | 52 | struct _QQStatusButtonClass { 53 | GtkComboBoxClass parent; 54 | 55 | /*< private >*/ 56 | GdkPixbuf *pb[STATUS_NUM]; 57 | GdkPixbuf *arrow; 58 | GdkCursor *hand_cursor; 59 | }; 60 | 61 | GType qq_statusbutton_get_type(); 62 | GtkWidget* qq_statusbutton_new(); 63 | 64 | // 65 | // Get the status 66 | // string or int 67 | // 68 | const gchar* qq_statusbutton_get_status_string(GtkWidget *btn); 69 | QQStatusButtonStatus qq_statusbutton_get_status(GtkWidget *btn); 70 | 71 | // 72 | // Set the status 73 | // 74 | void qq_statusbutton_set_status_string(GtkWidget *btn, const gchar *status); 75 | void qq_statusbutton_set_status(GtkWidget *btn, QQStatusButtonStatus status); 76 | #endif 77 | -------------------------------------------------------------------------------- /src/gui/tray.h: -------------------------------------------------------------------------------- 1 | #ifndef __GTKQQ_TRAY_H 2 | #define __GTKQQ_TRAY_H 3 | #include 4 | 5 | #define QQ_TRAY(obj) G_TYPE_CHECK_INSTANCE_CAST(obj, qq_tray_get_type(), QQTray) 6 | #define QQ_TRAYCLASS(c) G_TYPE_CHECK_CLASS_CAST(c, qq_tray_get_type()\ 7 | , QQTrayClass) 8 | #define QQ_IS_TRAY(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, qq_tray_get_type()) 9 | 10 | typedef struct __QQTray QQTray; 11 | typedef struct __QQTrayClass QQTrayClass; 12 | 13 | struct __QQTray{ 14 | GtkStatusIcon parent; 15 | }; 16 | 17 | struct __QQTrayClass{ 18 | GtkStatusIconClass parent; 19 | }; 20 | 21 | QQTray* qq_tray_new(); 22 | GType qq_tray_get_type(); 23 | 24 | 25 | /** 26 | * Blink the tray icon for the uin 27 | * If the tray icon is blinking, add the uin to the queue. 28 | */ 29 | void qq_tray_blinking_for(QQTray *tray, const gchar *uin); 30 | 31 | /** 32 | * Stop blinking for the uin. 33 | * If some uin is waiting for blinking, blink it. 34 | */ 35 | void qq_tray_stop_blinking_for(QQTray *tray, const gchar *uin); 36 | 37 | /** 38 | * Set mute item status, it usually called when user login. 39 | * 40 | * @param tray 41 | * @param mute 42 | */ 43 | void qq_tray_set_mute_item(QQTray *tray, gboolean mute); 44 | 45 | #endif /* __GTKQQ_TRAY_H */ 46 | -------------------------------------------------------------------------------- /src/include/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS = lwqq 2 | AUTOMAKE_OPTIONS = foreign no-dependencies 3 | -------------------------------------------------------------------------------- /src/include/lwqq/Makefile.am: -------------------------------------------------------------------------------- 1 | pkginclude_HEADERS = \ 2 | info.h logger.h login.h msg.h queue.h smemory.h type.h 3 | 4 | pkgincludedir= $(includedir)/lwqq 5 | -------------------------------------------------------------------------------- /src/include/lwqq/info.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file info.h 3 | * @author mathslinux 4 | * @date Sun May 27 19:49:51 2012 5 | * 6 | * @brief Fetch QQ information. e.g. friends information, group information. 7 | * 8 | * 9 | */ 10 | 11 | #ifndef LWQQ_INFO_H 12 | #define LWQQ_INFO_H 13 | 14 | #include "type.h" 15 | 16 | /** 17 | * Get QQ friends information. These information include basic friend 18 | * information, friends group information, and so on 19 | * 20 | * @param lc 21 | * @param err 22 | */ 23 | void lwqq_info_get_friends_info(LwqqClient *lc, LwqqErrorCode *err); 24 | 25 | /** 26 | * Get QQ groups' name information. Get only 'name', 'gid' , 'code' . 27 | * 28 | * @param lc 29 | * @param err 30 | */ 31 | void lwqq_info_get_group_name_list(LwqqClient *lc, LwqqErrorCode *err); 32 | 33 | /** 34 | * Get detail information of QQ friend(NB: include myself) 35 | * QQ server need us to pass param like: 36 | * tuin=244569070&verifysession=&code=&vfwebqq=e64da25c140c66 37 | * 38 | * @param lc 39 | * @param buddy 40 | * @param err 41 | */ 42 | void lwqq_info_get_friend_detail_info(LwqqClient *lc, LwqqBuddy *buddy, 43 | LwqqErrorCode *err); 44 | 45 | /** 46 | * Get all friends qqnumbers 47 | * 48 | * @param lc 49 | * @param err 50 | */ 51 | void lwqq_info_get_all_friend_qqnumbers(LwqqClient *lc, LwqqErrorCode *err); 52 | 53 | /** 54 | * Get friend qqnumber 55 | * 56 | * @param lc 57 | * @param uin 58 | * 59 | * @return qqnumber on sucessful, NB: caller is responsible for freeing 60 | * the memory returned by this function 61 | */ 62 | char *lwqq_info_get_friend_qqnumber(LwqqClient *lc, const char *uin); 63 | 64 | /** 65 | * Get QQ groups detail information. 66 | * 67 | * @param lc 68 | * @param group 69 | * @param err 70 | */ 71 | void lwqq_info_get_group_detail_info(LwqqClient *lc, LwqqGroup *group, 72 | LwqqErrorCode *err); 73 | 74 | /** 75 | * Get online buddies 76 | * NB : This function must be called after lwqq_info_get_friends_info() 77 | * because we stored buddy's status in buddy object which is created in 78 | * lwqq_info_get_friends_info() 79 | * 80 | * @param lc 81 | * @param err 82 | */ 83 | void lwqq_info_get_online_buddies(LwqqClient *lc, LwqqErrorCode *err); 84 | 85 | #endif /* LWQQ_INFO_H */ 86 | -------------------------------------------------------------------------------- /src/include/lwqq/logger.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file logger.h 3 | * @author mathslinux 4 | * @date Sun May 20 23:27:05 2012 5 | * 6 | * @brief Linux WebQQ Logger API 7 | * 8 | * 9 | */ 10 | 11 | #ifndef LWQQ_LOGGER_H 12 | #define LWQQ_LOGGER_H 13 | 14 | #define _A_ __FILE__, __LINE__, __PRETTY_FUNCTION__ 15 | #define _LOG_DEBUG 0 16 | #define LOG_DEBUG _LOG_DEBUG, _A_ 17 | 18 | #define __LOG_NOTICE 1 19 | #define LOG_NOTICE __LOG_NOTICE, _A_ 20 | 21 | #define __LOG_WARNING 2 22 | #define LOG_WARNING __LOG_WARNING, _A_ 23 | 24 | #define __LOG_ERROR 3 25 | #define LOG_ERROR __LOG_ERROR, _A_ 26 | 27 | /** 28 | * This is standard logger function 29 | * 30 | * @param level Which level of this message, e.g. debug 31 | * @param file Which file this function called in 32 | * @param line Which line this function call at 33 | * @param function Which function call this function 34 | * @param msg Log message 35 | */ 36 | void lwqq_log(int level, const char *file, int line, 37 | const char *function, const char* msg, ...); 38 | 39 | #endif /* LWQQ_LOGGER_H */ 40 | -------------------------------------------------------------------------------- /src/include/lwqq/login.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file login.h 3 | * @author mathslinux 4 | * @date Sun May 20 02:25:51 2012 5 | * 6 | * @brief Linux WebQQ Login API 7 | * 8 | * 9 | */ 10 | 11 | #ifndef LWQQ_LOGIN_H 12 | #define LWQQ_LOGIN_H 13 | 14 | #include "type.h" 15 | 16 | /** 17 | * WebQQ login function 18 | * 19 | * @param client Lwqq Client 20 | * @param err Error code 21 | */ 22 | void lwqq_login(LwqqClient *client, LwqqErrorCode *err); 23 | 24 | /** 25 | * WebQQ logout function 26 | * 27 | * @param client Lwqq Client 28 | * @param err Error code 29 | */ 30 | void lwqq_logout(LwqqClient *client, LwqqErrorCode *err); 31 | 32 | #endif /* LWQQ_LOGIN_H */ 33 | -------------------------------------------------------------------------------- /src/include/lwqq/msg.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file msg.h 3 | * @author mathslinux 4 | * @date Thu Jun 14 14:42:08 2012 5 | * 6 | * @brief 7 | * 8 | * 9 | */ 10 | 11 | #ifndef LWQQ_MSG_H 12 | #define LWQQ_MSG_H 13 | 14 | #include 15 | #include "queue.h" 16 | 17 | #define LWQQ_CONTENT_STRING 0 18 | #define LWQQ_CONTENT_FACE 1 19 | 20 | typedef struct LwqqMsgContent { 21 | int type; 22 | union { 23 | int face; 24 | char *str; 25 | } data; 26 | TAILQ_ENTRY(LwqqMsgContent) entries; 27 | } LwqqMsgContent ; 28 | 29 | typedef struct LwqqMsgMessage { 30 | char *from; 31 | char *to; 32 | time_t time; 33 | 34 | /* For font */ 35 | char *f_name; 36 | int f_size; 37 | struct { 38 | int a, b, c; /* bold , italic , underline */ 39 | } f_style; 40 | char *f_color; 41 | 42 | TAILQ_HEAD(, LwqqMsgContent) content; 43 | } LwqqMsgMessage; 44 | 45 | typedef struct LwqqMsgStatusChange { 46 | char *who; 47 | char *status; 48 | int client_type; 49 | } LwqqMsgStatusChange; 50 | 51 | typedef struct LwqqMsgKickMessage { 52 | int show_reason; 53 | char *reason; 54 | char *way; 55 | } LwqqMsgKickMessage; 56 | 57 | typedef enum LwqqMsgType { 58 | LWQQ_MT_BUDDY_MSG = 0, 59 | LWQQ_MT_GROUP_MSG, 60 | LWQQ_MT_STATUS_CHANGE, 61 | LWQQ_MT_KICK_MESSAGE, 62 | LWQQ_MT_UNKNOWN, 63 | } LwqqMsgType; 64 | 65 | typedef struct LwqqMsg { 66 | /* Message type. e.g. buddy message or group message */ 67 | LwqqMsgType type; 68 | void *opaque; /**< Message details */ 69 | } LwqqMsg; 70 | 71 | /** 72 | * Create a new LwqqMsg object 73 | * 74 | * @param msg_type 75 | * 76 | * @return NULL on failure 77 | */ 78 | LwqqMsg *lwqq_msg_new(LwqqMsgType type); 79 | 80 | /** 81 | * Free a LwqqMsg object 82 | * 83 | * @param msg 84 | */ 85 | void lwqq_msg_free(LwqqMsg *msg); 86 | 87 | /************************************************************************/ 88 | /* LwqqRecvMsg API */ 89 | /** 90 | * Lwqq Receive Message object, used by receiving message 91 | * 92 | */ 93 | typedef struct LwqqRecvMsg { 94 | LwqqMsg *msg; 95 | SIMPLEQ_ENTRY(LwqqRecvMsg) entries; 96 | } LwqqRecvMsg; 97 | 98 | typedef struct LwqqRecvMsgList { 99 | int count; /**< Number of message */ 100 | pthread_mutex_t mutex; 101 | SIMPLEQ_HEAD(, LwqqRecvMsg) head; 102 | void *lc; /**< Lwqq Client reference */ 103 | void (*poll_msg)(struct LwqqRecvMsgList *list); /**< Poll to fetch msg */ 104 | } LwqqRecvMsgList; 105 | 106 | /** 107 | * Create a new LwqqRecvMsgList object 108 | * 109 | * @param client Lwqq Client reference 110 | * 111 | * @return NULL on failure 112 | */ 113 | LwqqRecvMsgList *lwqq_recvmsg_new(void *client); 114 | 115 | /** 116 | * Free a LwqqRecvMsgList object 117 | * 118 | * @param list 119 | */ 120 | void lwqq_recvmsg_free(LwqqRecvMsgList *list); 121 | 122 | /* LwqqRecvMsg API end */ 123 | 124 | /************************************************************************/ 125 | int lwqq_msg_send(void *client, LwqqMsg *msg); 126 | int lwqq_msg_send2(void *client, const char *to, const char *content); 127 | /* LwqqSendMsg API */ 128 | 129 | #endif /* LWQQ_MSG_H */ 130 | -------------------------------------------------------------------------------- /src/include/lwqq/smemory.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file smemory.h 3 | * @author mathslinux 4 | * @date Tue May 22 00:41:48 2012 5 | * 6 | * @brief Small Memory Wrapper 7 | * 8 | * 9 | */ 10 | 11 | 12 | #ifndef SMEMORY_H 13 | #define SMEMORY_H 14 | 15 | #include 16 | #include 17 | 18 | void *s_malloc(size_t size); 19 | void *s_malloc0(size_t size); 20 | void *s_calloc(size_t nmemb, size_t lsize); 21 | void *s_realloc(void *ptr, size_t size); 22 | void s_free(void *p); 23 | char *s_strdup(const char *s1); 24 | char *s_strndup(const char *s1, size_t n); 25 | int s_vasprintf(char **buf, const char * format, va_list arg); 26 | int s_asprintf(char **buf, const char *format, ...); 27 | 28 | #endif /* SMEMORY_H */ 29 | -------------------------------------------------------------------------------- /src/include/lwqq/type.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file type.h 3 | * @author mathslinux 4 | * @date Sun May 20 22:24:30 2012 5 | * 6 | * @brief Linux WebQQ Data Struct API 7 | * 8 | * 9 | */ 10 | 11 | #ifndef LWQQ_TYPE_H 12 | #define LWQQ_TYPE_H 13 | 14 | #include "queue.h" 15 | #include "msg.h" 16 | 17 | /************************************************************************/ 18 | /* Struct defination */ 19 | 20 | typedef struct LwqqFriendCategory { 21 | int index; 22 | int sort; 23 | char *name; 24 | int count; 25 | LIST_ENTRY(LwqqFriendCategory) entries; 26 | } LwqqFriendCategory; 27 | 28 | /* QQ buddy */ 29 | typedef struct LwqqBuddy { 30 | char *uin; /**< Uin. Change every login */ 31 | char *qqnumber; /**< QQ number */ 32 | char *face; 33 | char *occupation; 34 | char *phone; 35 | char *allow; 36 | char *college; 37 | char *reg_time; 38 | char *constel; 39 | char *blood; 40 | char *homepage; 41 | char *stat; 42 | char *country; 43 | char *city; 44 | char *personal; 45 | char *nick; 46 | char *long_nick; 47 | char *shengxiao; 48 | char *email; 49 | char *province; 50 | char *gender; 51 | char *mobile; 52 | char *vip_info; 53 | char *markname; 54 | 55 | char *flag; 56 | 57 | char *cate_index; /**< Index of the category */ 58 | 59 | /* 60 | * 1 : Desktop client 61 | * 21: Mobile client 62 | * 41: Web QQ Client 63 | */ 64 | char *client_type; 65 | 66 | char *status; /* Online status */ 67 | pthread_mutex_t mutex; 68 | LIST_ENTRY(LwqqBuddy) entries; /* FIXME: Do we really need this? */ 69 | } LwqqBuddy; 70 | 71 | /* QQ group */ 72 | typedef struct LwqqGroup { 73 | char *name; /**< QQ Group name */ 74 | char *gid; 75 | char *code; 76 | char *account; /** < QQ Group number */ 77 | char *markname; /** < QQ Group mark name */ 78 | 79 | /* ginfo */ 80 | char *face; 81 | char *memo; 82 | char *class; 83 | char *fingermemo; 84 | char *createtime; 85 | char *level; 86 | char *owner; /** < owner's QQ number */ 87 | char *flag; 88 | char *option; 89 | 90 | LIST_ENTRY(LwqqGroup) entries; 91 | LIST_HEAD(, LwqqBuddy) members; /** < QQ Group members */ 92 | } LwqqGroup; 93 | 94 | typedef struct LwqqVerifyCode { 95 | char *str; 96 | char *type; 97 | char *img; 98 | char *uin; 99 | } LwqqVerifyCode ; 100 | 101 | typedef struct LwqqCookies { 102 | char *ptvfsession; /**< ptvfsession */ 103 | char *ptcz; 104 | char *skey; 105 | char *ptwebqq; 106 | char *ptuserinfo; 107 | char *uin; 108 | char *ptisp; 109 | char *pt2gguin; 110 | char *verifysession; 111 | char *lwcookies; 112 | } LwqqCookies; 113 | 114 | /* LwqqClient API */ 115 | typedef struct LwqqClient { 116 | char *username; /**< Username */ 117 | char *password; /**< Password */ 118 | LwqqBuddy *myself; /**< Myself */ 119 | char *version; /**< WebQQ version */ 120 | LwqqVerifyCode *vc; /**< Verify Code */ 121 | char *clientid; 122 | char *seskey; 123 | char *cip; 124 | char *index; 125 | char *port; 126 | char *status; 127 | char *vfwebqq; 128 | char *psessionid; 129 | LwqqCookies *cookies; 130 | LIST_HEAD(, LwqqBuddy) friends; /**< QQ friends */ 131 | LIST_HEAD(, LwqqFriendCategory) categories; /**< QQ friends categories */ 132 | LIST_HEAD(, LwqqGroup) groups; /**< QQ groups */ 133 | LwqqRecvMsgList *msg_list; 134 | long msg_id; /**< Used to send message */ 135 | } LwqqClient; 136 | 137 | /* Lwqq Error Code */ 138 | typedef enum { 139 | LWQQ_EC_OK, 140 | LWQQ_EC_ERROR, 141 | LWQQ_EC_NULL_POINTER, 142 | LWQQ_EC_FILE_NOT_EXIST, 143 | LWQQ_EC_LOGIN_NEED_VC = 10, 144 | LWQQ_EC_NETWORK_ERROR = 20, 145 | LWQQ_EC_HTTP_ERROR = 30, 146 | LWQQ_EC_DB_EXEC_FAIELD = 50, 147 | LWQQ_EC_DB_CLOSE_FAILED, 148 | } LwqqErrorCode; 149 | 150 | /* Struct defination end */ 151 | 152 | /************************************************************************/ 153 | /* LwqqClient API */ 154 | /** 155 | * Create a new lwqq client 156 | * 157 | * @param username QQ username 158 | * @param password QQ password 159 | * 160 | * @return A new LwqqClient instance, or NULL failed 161 | */ 162 | LwqqClient *lwqq_client_new(const char *username, const char *password); 163 | 164 | /** 165 | * Get cookies needby by webqq server 166 | * 167 | * @param lc 168 | * 169 | * @return Cookies string on success, or null on failure 170 | */ 171 | char *lwqq_get_cookies(LwqqClient *lc); 172 | 173 | /** 174 | * Free LwqqVerifyCode object 175 | * 176 | * @param vc 177 | */ 178 | void lwqq_vc_free(LwqqVerifyCode *vc); 179 | 180 | /** 181 | * Free LwqqClient instance 182 | * 183 | * @param client LwqqClient instance 184 | */ 185 | void lwqq_client_free(LwqqClient *client); 186 | 187 | /* LwqqClient API end */ 188 | 189 | /************************************************************************/ 190 | /* LwqqBuddy API */ 191 | /** 192 | * 193 | * Create a new buddy 194 | * 195 | * @return A LwqqBuddy instance 196 | */ 197 | LwqqBuddy *lwqq_buddy_new(); 198 | 199 | /** 200 | * Free a LwqqBuddy instance 201 | * 202 | * @param buddy 203 | */ 204 | void lwqq_buddy_free(LwqqBuddy *buddy); 205 | 206 | /** 207 | * Find buddy object by buddy's uin member 208 | * 209 | * @param lc Our Lwqq client object 210 | * @param uin The uin of buddy which we want to find 211 | * 212 | * @return 213 | */ 214 | LwqqBuddy *lwqq_buddy_find_buddy_by_uin(LwqqClient *lc, const char *uin); 215 | 216 | /* LwqqBuddy API END*/ 217 | 218 | 219 | /** 220 | * Free a LwqqGroup instance 221 | * 222 | * @param group 223 | */ 224 | void lwqq_group_free(LwqqGroup *group); 225 | 226 | /** 227 | * 228 | * Create a new group 229 | * 230 | * @return A LwqqGroup instance 231 | */ 232 | LwqqGroup *lwqq_group_new(); 233 | 234 | /** 235 | * Find group object by group's gid member 236 | * 237 | * @param lc Our Lwqq client object 238 | * @param uin The gid of group which we want to find 239 | * 240 | * @return A LwqqGroup instance 241 | */ 242 | LwqqGroup *lwqq_group_find_group_by_gid(LwqqClient *lc, const char *gid); 243 | 244 | /** 245 | * Find group member object by member's uin 246 | * 247 | * @param group Our Lwqq group object 248 | * @param uin The uin of group member which we want to find 249 | * 250 | * @return A LwqqBuddy instance 251 | */ 252 | LwqqBuddy *lwqq_group_find_group_member_by_uin(LwqqGroup *group, const char *uin); 253 | 254 | /************************************************************************/ 255 | 256 | #endif /* LWQQ_TYPE_H */ 257 | -------------------------------------------------------------------------------- /src/liblwqq/Makefile.am: -------------------------------------------------------------------------------- 1 | SUBDIRS=libghttp 2 | lib_LTLIBRARIES=liblwqq.la 3 | liblwqq_la_CPPFLAGS=-I./libghttp -I../include/lwqq ${LIBEV_CFLAGS} ${CURL_CFLAGS} 4 | liblwqq_la_LIBADD= 5 | liblwqq_la_SOURCES=logger.c login.c type.c smemory.c\ 6 | http.c md5.c url.c json.c info.c msg.c \ 7 | unicode.c http_curl.c 8 | AM_CFLAGS = 9 | 10 | -------------------------------------------------------------------------------- /src/liblwqq/http.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file http.h 3 | * @author mathslinux 4 | * @date Mon May 21 23:07:29 2012 5 | * 6 | * @brief Linux WebQQ Http API 7 | * 8 | * 9 | */ 10 | 11 | #ifndef LWQQ_HTTP_H 12 | #define LWQQ_HTTP_H 13 | 14 | #include "type.h" 15 | 16 | typedef int (*LwqqAsyncCallback)(LwqqErrorCode ec, char *response, void* data); 17 | 18 | /** 19 | * Lwqq Http request struct, this http object worked donw for lwqq, 20 | * But for other app, it may work bad. 21 | * 22 | */ 23 | typedef struct LwqqHttpRequest { 24 | void *req; 25 | 26 | /** 27 | * Http code return from server. e.g. 200, 404, this maybe changed 28 | * after do_request() called. 29 | */ 30 | int http_code; 31 | 32 | /* Server response, used when do async request */ 33 | char *response; 34 | 35 | /* Response length, NB: the response may not terminate with '\0' */ 36 | int resp_len; 37 | 38 | /** 39 | * Send a request to server, method is GET(0) or POST(1), if we make a 40 | * POST request, we must provide a http body. 41 | */ 42 | int (*do_request)(struct LwqqHttpRequest *request, int method, char *body); 43 | 44 | /** 45 | * Send a request to server asynchronous, method is GET(0) or POST(1), 46 | * if we make a POST request, we must provide a http body. 47 | */ 48 | int (*do_request_async)(struct LwqqHttpRequest *request, int method, 49 | char *body, LwqqAsyncCallback callback, void *data); 50 | 51 | /* Set our http client header */ 52 | void (*set_header)(struct LwqqHttpRequest *request, const char *name, 53 | const char *value); 54 | 55 | /* Set default http header */ 56 | void (*set_default_header)(struct LwqqHttpRequest *request); 57 | 58 | /** 59 | * Get header, return a alloca memory, so caller has responsibility 60 | * free the memory 61 | */ 62 | char * (*get_header)(struct LwqqHttpRequest *request, const char *name); 63 | 64 | /** 65 | * Get Cookie, return a alloca memory, so caller has responsibility 66 | * free the memory 67 | */ 68 | char * (*get_cookie)(struct LwqqHttpRequest *request, const char *name); 69 | 70 | } LwqqHttpRequest; 71 | 72 | /** 73 | * Free Http Request 74 | * 75 | * @param request 76 | */ 77 | void lwqq_http_request_free(LwqqHttpRequest *request); 78 | 79 | /** 80 | * Create a new Http request instance 81 | * 82 | * @param uri Request service from 83 | * 84 | * @return 85 | */ 86 | LwqqHttpRequest *lwqq_http_request_new(const char *uri); 87 | 88 | /** 89 | * Create a default http request object using default http header. 90 | * 91 | * @param url Which your want send this request to 92 | * @param err This parameter can be null, if so, we dont give thing 93 | * error information. 94 | * 95 | * @return Null if failed, else a new http request object 96 | */ 97 | LwqqHttpRequest *lwqq_http_create_default_request(const char *url, 98 | LwqqErrorCode *err); 99 | 100 | #endif /* LWQQ_HTTP_H */ 101 | -------------------------------------------------------------------------------- /src/liblwqq/http_curl.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file http_curl.c 3 | * @author mathslinux 4 | * @date Sun Aug 19 16:46:22 2012 5 | * 6 | * @brief Use asynchronous http translation 7 | * 8 | * 9 | */ 10 | 11 | #ifdef USE_ASYNC_HTTP 12 | #endif /* USE_ASYNC_HTTP */ 13 | -------------------------------------------------------------------------------- /src/liblwqq/libghttp/Makefile.am: -------------------------------------------------------------------------------- 1 | lib_LTLIBRARIES=libghttp.la 2 | libghttp_la_CPPFLAGS= -I./libghttp 3 | libghttp_la_LIBADD= 4 | libghttp_la_SOURCES= ghttp.c http_base64.h \ 5 | http_hdrs.c http_resp.c\ 6 | http_uri.c ghttp_constants.h\ 7 | http_date.c http_hdrs.h\ 8 | http_resp.h http_uri.h \ 9 | ghttp.h http_date.h\ 10 | http_req.c http_trans.c\ 11 | http_base64.c http_global.h\ 12 | http_req.h http_trans.h 13 | AM_CFLAGS = 14 | -------------------------------------------------------------------------------- /src/liblwqq/libghttp/ghttp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ghttp.h -- A public interface to common http functions 3 | * Created: Christopher Blizzard , 21-Aug-1998 4 | * 5 | * Copyright (C) 1998 Free Software Foundation 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Library General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Library General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Library General Public 18 | * License along with this library; if not, write to the Free 19 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | */ 21 | 22 | #ifndef GHTTP_H 23 | #define GHTTP_H 24 | 25 | #include 26 | #include 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif /* __cplusplus */ 31 | 32 | typedef struct _ghttp_request ghttp_request; 33 | 34 | typedef enum ghttp_type_tag 35 | { 36 | ghttp_type_get = 0, 37 | ghttp_type_options, 38 | ghttp_type_head, 39 | ghttp_type_post, 40 | ghttp_type_put, 41 | ghttp_type_delete, 42 | ghttp_type_trace, 43 | ghttp_type_connect, 44 | ghttp_type_propfind, 45 | ghttp_type_proppatch, 46 | ghttp_type_mkcol, 47 | ghttp_type_copy, 48 | ghttp_type_move, 49 | ghttp_type_lock, 50 | ghttp_type_unlock 51 | } ghttp_type; 52 | 53 | typedef enum ghttp_sync_mode_tag 54 | { 55 | ghttp_sync = 0, 56 | ghttp_async 57 | } ghttp_sync_mode; 58 | 59 | typedef enum ghttp_status_tag 60 | { 61 | ghttp_error = -1, 62 | ghttp_not_done, 63 | ghttp_done 64 | } ghttp_status; 65 | 66 | typedef enum ghttp_proc_tag 67 | { 68 | ghttp_proc_none = 0, 69 | ghttp_proc_request, 70 | ghttp_proc_response_hdrs, 71 | ghttp_proc_response 72 | } ghttp_proc; 73 | 74 | typedef struct ghttp_current_status_tag 75 | { 76 | ghttp_proc proc; /* what's it doing? */ 77 | int bytes_read; /* how many bytes have been read? */ 78 | int bytes_total; /* how many total */ 79 | } ghttp_current_status; 80 | 81 | /* create a new request object */ 82 | ghttp_request * 83 | ghttp_request_new(void); 84 | 85 | /* delete a current request object */ 86 | void 87 | ghttp_request_destroy(ghttp_request *a_request); 88 | 89 | /* Validate a uri 90 | * This will return -1 if a uri is invalid 91 | */ 92 | int 93 | ghttp_uri_validate(char *a_uri); 94 | 95 | /* Set a uri in a request 96 | * This will return -1 if the uri is invalid 97 | */ 98 | 99 | int 100 | ghttp_set_uri(ghttp_request *a_request, char *a_uri); 101 | 102 | /* Set a proxy for a request 103 | * This will return -1 if the uri is invalid 104 | */ 105 | 106 | int 107 | ghttp_set_proxy(ghttp_request *a_request, char *a_uri); 108 | 109 | /* Set a request type 110 | * This will return -1 if the request type is invalid or 111 | * unsupported 112 | */ 113 | 114 | int 115 | ghttp_set_type(ghttp_request *a_request, ghttp_type a_type); 116 | 117 | /* Set the body. 118 | * This will return -1 if the request type doesn't support it 119 | */ 120 | 121 | int 122 | ghttp_set_body(ghttp_request *a_request, char *a_body, int a_len); 123 | 124 | /* Set whether or not you want to use sync or async mode. 125 | */ 126 | 127 | int 128 | ghttp_set_sync(ghttp_request *a_request, 129 | ghttp_sync_mode a_mode); 130 | 131 | /* Prepare a request. 132 | * Call this before trying to process a request or if you change the 133 | * uri. 134 | */ 135 | 136 | int 137 | ghttp_prepare(ghttp_request *a_request); 138 | 139 | /* Set the chunk size 140 | * You might want to do this to optimize for different connection speeds. 141 | */ 142 | 143 | void 144 | ghttp_set_chunksize(ghttp_request *a_request, int a_size); 145 | 146 | /* Set a random request header 147 | */ 148 | 149 | void 150 | ghttp_set_header(ghttp_request *a_request, 151 | const char *a_hdr, const char *a_val); 152 | 153 | /* Process a request 154 | */ 155 | 156 | ghttp_status 157 | ghttp_process(ghttp_request *a_request); 158 | 159 | /* Get the status of a request 160 | */ 161 | 162 | ghttp_current_status 163 | ghttp_get_status(ghttp_request *a_request); 164 | 165 | /* Flush the received data (so far) into the response body. This is 166 | * useful for asynchronous requests with large responses: you can 167 | * periodically flush the response buffer and parse the data that's 168 | * arrived so far. 169 | */ 170 | 171 | void 172 | ghttp_flush_response_buffer(ghttp_request *a_request); 173 | 174 | /* Get the value of a random response header 175 | */ 176 | 177 | const char * 178 | ghttp_get_header(ghttp_request *a_request, 179 | const char *a_hdr); 180 | 181 | /* Get a_name's cookie, caller must free the return string */ 182 | char * ghttp_get_cookie(ghttp_request *a_request, const char *a_hdr); 183 | 184 | /* Get the list of headers that were returned in the response. You 185 | must free the returned string values. This function will return 0 186 | on success, -1 on some kind of error. */ 187 | int 188 | ghttp_get_header_names(ghttp_request *a_request, 189 | char ***a_hdrs, int *a_num_hdrs); 190 | 191 | /* Abort a currently running request. */ 192 | int 193 | ghttp_close(ghttp_request *a_request); 194 | 195 | /* Clean a request 196 | */ 197 | void 198 | ghttp_clean(ghttp_request *a_request); 199 | 200 | /* Get the socket associated with a particular connection 201 | */ 202 | 203 | int 204 | ghttp_get_socket(ghttp_request *a_request); 205 | 206 | /* get the return entity body 207 | */ 208 | 209 | char * 210 | ghttp_get_body(ghttp_request *a_request); 211 | 212 | /* get the returned length 213 | */ 214 | 215 | int 216 | ghttp_get_body_len(ghttp_request *a_request); 217 | 218 | /* Get an error message for a request that has failed. 219 | */ 220 | 221 | const char * 222 | ghttp_get_error(ghttp_request *a_request); 223 | 224 | /* Parse a date string that is one of the standard 225 | * date formats 226 | */ 227 | 228 | time_t 229 | ghttp_parse_date(char *a_date); 230 | 231 | /* Return the status code. 232 | */ 233 | 234 | int 235 | ghttp_status_code(ghttp_request *a_request); 236 | 237 | /* Return the reason phrase. 238 | */ 239 | 240 | const char * 241 | ghttp_reason_phrase(ghttp_request *a_request); 242 | 243 | /* Set your username/password pair 244 | */ 245 | 246 | int 247 | ghttp_set_authinfo(ghttp_request *a_request, 248 | const char *a_user, 249 | const char *a_pass); 250 | 251 | 252 | /* Set your username/password pair for proxy 253 | */ 254 | 255 | int 256 | ghttp_set_proxy_authinfo(ghttp_request *a_request, 257 | const char *a_user, 258 | const char *a_pass); 259 | 260 | 261 | #ifdef __cplusplus 262 | } 263 | #endif /* __cplusplus */ 264 | 265 | 266 | #endif /* GHTTP_H */ 267 | -------------------------------------------------------------------------------- /src/liblwqq/libghttp/ghttp_constants.h: -------------------------------------------------------------------------------- 1 | /* 2 | * ghttp_constants.h -- definitions for char constants that people 3 | * might want to use 4 | * Created: Christopher Blizzard 5 | * 6 | * Copyright (C) 1998 Free Software Foundation 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Library General Public 10 | * License as published by the Free Software Foundation; either 11 | * version 2 of the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Library General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Library General Public 19 | * License along with this library; if not, write to the Free 20 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 | */ 22 | 23 | #ifndef GHTTP_CONSTANTS_H 24 | #define GHTTP_CONSTANTS_H 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif /* __cplusplus */ 29 | 30 | extern const char http_hdr_Allow[]; 31 | extern const char http_hdr_Content_Encoding[]; 32 | extern const char http_hdr_Content_Language[]; 33 | extern const char http_hdr_Content_Length[]; 34 | extern const char http_hdr_Content_Location[]; 35 | extern const char http_hdr_Content_MD5[]; 36 | extern const char http_hdr_Content_Range[]; 37 | extern const char http_hdr_Content_Type[]; 38 | extern const char http_hdr_Expires[]; 39 | extern const char http_hdr_Last_Modified[]; 40 | 41 | /* general headers */ 42 | 43 | extern const char http_hdr_Cache_Control[]; 44 | extern const char http_hdr_Connection[]; 45 | extern const char http_hdr_Date[]; 46 | extern const char http_hdr_Pragma[]; 47 | extern const char http_hdr_Transfer_Encoding[]; 48 | extern const char http_hdr_Update[]; 49 | extern const char http_hdr_Trailer[]; 50 | extern const char http_hdr_Via[]; 51 | 52 | /* request headers */ 53 | 54 | extern const char http_hdr_Accept[]; 55 | extern const char http_hdr_Accept_Charset[]; 56 | extern const char http_hdr_Accept_Encoding[]; 57 | extern const char http_hdr_Accept_Language[]; 58 | extern const char http_hdr_Authorization[]; 59 | extern const char http_hdr_Expect[]; 60 | extern const char http_hdr_From[]; 61 | extern const char http_hdr_Host[]; 62 | extern const char http_hdr_If_Modified_Since[]; 63 | extern const char http_hdr_If_Match[]; 64 | extern const char http_hdr_If_None_Match[]; 65 | extern const char http_hdr_If_Range[]; 66 | extern const char http_hdr_If_Unmodified_Since[]; 67 | extern const char http_hdr_Max_Forwards[]; 68 | extern const char http_hdr_Proxy_Authorization[]; 69 | extern const char http_hdr_Range[]; 70 | extern const char http_hdr_Referrer[]; 71 | extern const char http_hdr_TE[]; 72 | extern const char http_hdr_User_Agent[]; 73 | 74 | /* response headers */ 75 | 76 | extern const char http_hdr_Accept_Ranges[]; 77 | extern const char http_hdr_Age[]; 78 | extern const char http_hdr_ETag[]; 79 | extern const char http_hdr_Location[]; 80 | extern const char http_hdr_Retry_After[]; 81 | extern const char http_hdr_Server[]; 82 | extern const char http_hdr_Vary[]; 83 | extern const char http_hdr_Warning[]; 84 | extern const char http_hdr_WWW_Authenticate[]; 85 | 86 | /* Other headers */ 87 | 88 | extern const char http_hdr_Set_Cookie[]; 89 | 90 | /* WebDAV headers */ 91 | 92 | extern const char http_hdr_DAV[]; 93 | extern const char http_hdr_Depth[]; 94 | extern const char http_hdr_Destination[]; 95 | extern const char http_hdr_If[]; 96 | extern const char http_hdr_Lock_Token[]; 97 | extern const char http_hdr_Overwrite[]; 98 | extern const char http_hdr_Status_URI[]; 99 | extern const char http_hdr_Timeout[]; 100 | 101 | #ifdef __cplusplus 102 | } 103 | #endif /* __cplusplus */ 104 | 105 | #endif /* GHTTP_CONSTANTS_H */ 106 | -------------------------------------------------------------------------------- /src/liblwqq/libghttp/http_base64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * http_base64.c -- This file contains code for encoding strings with base64. 3 | * Created: Christopher Blizzard , 20-Nov-1998 4 | * Author: Joe Orton 5 | * 6 | * Copyright (C) 1998 Free Software Foundation 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Library General Public 10 | * License as published by the Free Software Foundation; either 11 | * version 2 of the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Library General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Library General Public 19 | * License along with this library; if not, write to the Free 20 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | const char b64_alphabet[65] = { 28 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 29 | "abcdefghijklmnopqrstuvwxyz" 30 | "0123456789+/=" }; 31 | 32 | char * 33 | http_base64_encode(const char *text) { 34 | /* The tricky thing about this is doing the padding at the end, 35 | * doing the bit manipulation requires a bit of concentration only */ 36 | char *buffer = NULL; 37 | char *point = NULL; 38 | int inlen = 0; 39 | int outlen = 0; 40 | 41 | /* check our args */ 42 | if (text == NULL) 43 | return NULL; 44 | 45 | /* Use 'buffer' to store the output. Work out how big it should be... 46 | * This must be a multiple of 4 bytes */ 47 | 48 | inlen = strlen( text ); 49 | /* check our arg...avoid a pesky FPE */ 50 | if (inlen == 0) 51 | { 52 | buffer = malloc(sizeof(char)); 53 | buffer[0] = '\0'; 54 | return buffer; 55 | } 56 | outlen = (inlen*4)/3; 57 | if( (inlen % 3) > 0 ) /* got to pad */ 58 | outlen += 4 - (inlen % 3); 59 | 60 | buffer = malloc( outlen + 1 ); /* +1 for the \0 */ 61 | memset(buffer, 0, outlen + 1); /* initialize to zero */ 62 | 63 | /* now do the main stage of conversion, 3 bytes at a time, 64 | * leave the trailing bytes (if there are any) for later */ 65 | 66 | for( point=buffer; inlen>=3; inlen-=3, text+=3 ) { 67 | *(point++) = b64_alphabet[ *text>>2 ]; 68 | *(point++) = b64_alphabet[ (*text<<4 & 0x30) | *(text+1)>>4 ]; 69 | *(point++) = b64_alphabet[ (*(text+1)<<2 & 0x3c) | *(text+2)>>6 ]; 70 | *(point++) = b64_alphabet[ *(text+2) & 0x3f ]; 71 | } 72 | 73 | /* Now deal with the trailing bytes */ 74 | if( inlen ) { 75 | /* We always have one trailing byte */ 76 | *(point++) = b64_alphabet[ *text>>2 ]; 77 | *(point++) = b64_alphabet[ (*text<<4 & 0x30) | 78 | (inlen==2?*(text+1)>>4:0) ]; 79 | *(point++) = (inlen==1?'=':b64_alphabet[ *(text+1)<<2 & 0x3c ] ); 80 | *(point++) = '='; 81 | } 82 | 83 | *point = '\0'; 84 | 85 | return buffer; 86 | } 87 | -------------------------------------------------------------------------------- /src/liblwqq/libghttp/http_base64.h: -------------------------------------------------------------------------------- 1 | /* 2 | * http_base64.h -- Header file for base64 function(s). 3 | * Created: Christopher Blizzard , 20-Nov-1998 4 | * 5 | * Copyright (C) 1998 Free Software Foundation 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Library General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Library General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Library General Public 18 | * License along with this library; if not, write to the Free 19 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | */ 21 | 22 | #ifndef HTTP_BASE64_H 23 | #define HTTP_BASE64_H 24 | 25 | char * 26 | http_base64_encode(const char *text); 27 | 28 | #endif /* HTTP_BASE64_H */ 29 | -------------------------------------------------------------------------------- /src/liblwqq/libghttp/http_date.h: -------------------------------------------------------------------------------- 1 | /* 2 | * http_date.h -- Routines for parsing and generating http dates 3 | * Created: Christoper Blizzard , 16-Aug-1998 4 | * 5 | * Copyright (C) 1998 Free Software Foundation 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Library General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Library General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Library General Public 18 | * License along with this library; if not, write to the Free 19 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | */ 21 | 22 | #ifndef HTTP_DATE_H 23 | #define HTTP_DATE_H 24 | 25 | #include 26 | 27 | time_t 28 | http_date_to_time(const char *a_date); 29 | 30 | #endif /* HTTP_DATE_H */ 31 | -------------------------------------------------------------------------------- /src/liblwqq/libghttp/http_global.h: -------------------------------------------------------------------------------- 1 | /* 2 | * http_global.h -- Definitions for things that will be used throughout 3 | * the library. 4 | * Created: Christopher Blizzard , 16-Aug-1998 5 | * 6 | * Copyright (C) 1998 Free Software Foundation 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Library General Public 10 | * License as published by the Free Software Foundation; either 11 | * version 2 of the License, or (at your option) any later version. 12 | * 13 | * This library is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * Library General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Library General Public 19 | * License along with this library; if not, write to the Free 20 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 21 | */ 22 | 23 | #ifndef HTTP_GLOBAL_H 24 | #define HTTP_GLOBAL_H 25 | 26 | #define HTTP_TRANS_ERR -1 27 | #define HTTP_TRANS_NOT_DONE 1 28 | #define HTTP_TRANS_DONE 2 29 | 30 | #define HTTP_TRANS_SYNC 0 31 | #define HTTP_TRANS_ASYNC 1 32 | 33 | #endif /* GHTTP_GLOBAL_H */ 34 | -------------------------------------------------------------------------------- /src/liblwqq/libghttp/http_hdrs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * http_hdrs.h -- This file contains declarations for http headers 3 | * Created: Christopher Blizzard , 3-Aug-1998 4 | * 5 | * Copyright (C) 1998 Free Software Foundation 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Library General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Library General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Library General Public 18 | * License along with this library; if not, write to the Free 19 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | */ 21 | 22 | #ifndef HTTP_HDRS_H 23 | #define HTTP_HDRS_H 24 | 25 | #include "ghttp_constants.h" 26 | 27 | /* the list of known headers */ 28 | extern const char *http_hdr_known_list[]; 29 | 30 | /* a header list */ 31 | #define HTTP_HDRS_MAX 256 32 | typedef struct http_hdr_list_tag 33 | { 34 | char *header[HTTP_HDRS_MAX]; 35 | char *value[HTTP_HDRS_MAX]; 36 | } http_hdr_list; 37 | 38 | /* functions dealing with headers */ 39 | 40 | /* check to see if the library knows about the header */ 41 | const char * 42 | http_hdr_is_known(const char *a_hdr); 43 | 44 | /* create a new list */ 45 | http_hdr_list * 46 | http_hdr_list_new(void); 47 | 48 | /* destroy a list */ 49 | void 50 | http_hdr_list_destroy(http_hdr_list *a_list); 51 | 52 | /* set a value in a list */ 53 | int 54 | http_hdr_set_value(http_hdr_list *a_list, 55 | const char *a_name, 56 | const char *a_val); 57 | 58 | /* set the value in a list from a range, not a NTS */ 59 | int 60 | http_hdr_set_value_no_nts(http_hdr_list *a_list, 61 | const char *a_name_start, 62 | int a_name_len, 63 | const char *a_val_start, 64 | int a_val_len); 65 | 66 | /* get a copy of a value in a list */ 67 | char * 68 | http_hdr_get_value(http_hdr_list *a_list, 69 | const char *a_name); 70 | 71 | /* Get a_name's cookie, caller must free the return string */ 72 | char * 73 | http_hdr_get_cookie(http_hdr_list *a_list, 74 | const char *a_name); 75 | 76 | /* get a copy of the headers in a list */ 77 | int 78 | http_hdr_get_headers(http_hdr_list *a_list, 79 | char ***a_names, 80 | int *a_num_names); 81 | 82 | /* clear a header in a list */ 83 | int 84 | http_hdr_clear_value(http_hdr_list *a_list, 85 | const char *a_name); 86 | 87 | 88 | #endif /* HTTP_HDRS_H */ 89 | -------------------------------------------------------------------------------- /src/liblwqq/libghttp/http_req.c: -------------------------------------------------------------------------------- 1 | /* 2 | * http_req.c -- Functions for making http requests 3 | * Created: Christopher Blizzard , 6-Aug-1998 4 | * 5 | * Copyright (C) 1998 Free Software Foundation 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Library General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Library General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Library General Public 18 | * License along with this library; if not, write to the Free 19 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | */ 21 | 22 | #include 23 | #include 24 | #include "http_req.h" 25 | #include "http_trans.h" 26 | #include "http_global.h" 27 | 28 | const char * 29 | http_req_type_char[] = { 30 | "GET", 31 | "OPTIONS", 32 | "HEAD", 33 | "POST", 34 | "PUT", 35 | "DELETE", 36 | "TRACE", 37 | "CONNECT", 38 | "PROPFIND", 39 | "PROPPATCH", 40 | "MKCOL", 41 | "COPY", 42 | "MOVE", 43 | "LOCK", 44 | "UNLOCK", 45 | NULL 46 | }; 47 | 48 | http_req * 49 | http_req_new(void) 50 | { 51 | http_req *l_return = NULL; 52 | 53 | l_return = (http_req *)malloc(sizeof(http_req)); 54 | memset(l_return, 0, sizeof(http_req)); 55 | /* default to 1.1 */ 56 | l_return->http_ver = 1.1; 57 | l_return->headers = http_hdr_list_new(); 58 | return l_return; 59 | } 60 | 61 | void 62 | http_req_destroy(http_req *a_req) 63 | { 64 | if (!a_req) 65 | return; 66 | if (a_req->headers) 67 | http_hdr_list_destroy(a_req->headers); 68 | free(a_req); 69 | } 70 | 71 | int 72 | http_req_prepare(http_req *a_req) 73 | { 74 | int l_return = 0; 75 | char l_buf[30]; 76 | 77 | if (!a_req) 78 | return -1; 79 | memset(l_buf, 0, 30); 80 | /* set the host header */ 81 | http_hdr_set_value(a_req->headers, 82 | http_hdr_Host, 83 | a_req->host); 84 | /* check to see if we have an entity body */ 85 | if ((a_req->type == http_req_type_post) || 86 | (a_req->type == http_req_type_put) || 87 | (a_req->type == http_req_type_trace)) 88 | { 89 | sprintf(l_buf, "%d", a_req->body_len); 90 | http_hdr_set_value(a_req->headers, 91 | http_hdr_Content_Length, 92 | l_buf); 93 | } 94 | /* if the user agent isn't set then set a default */ 95 | if (http_hdr_get_value(a_req->headers, http_hdr_User_Agent) == NULL) 96 | http_hdr_set_value(a_req->headers, http_hdr_User_Agent, 97 | "libghttp/1.0"); 98 | return l_return; 99 | } 100 | 101 | int 102 | http_req_send(http_req *a_req, http_trans_conn *a_conn) 103 | { 104 | char *l_request = NULL; 105 | int l_request_len = 0; 106 | int i = 0; 107 | int l_len = 0; 108 | int l_headers_len = 0; 109 | int l_rv = 0; 110 | char *l_content = NULL; 111 | 112 | /* see if we need to jump into the function somewhere */ 113 | if (a_conn->sync == HTTP_TRANS_ASYNC) 114 | { 115 | if (a_req->state == http_req_state_sending_request) 116 | goto http_req_state_sending_request_jump; 117 | if (a_req->state == http_req_state_sending_headers) 118 | goto http_req_state_sending_headers_jump; 119 | if (a_req->state == http_req_state_sending_body) 120 | goto http_req_state_sending_body_jump; 121 | } 122 | /* enough for the request and the other little headers */ 123 | l_request = malloc(30 + strlen(a_req->resource) + (a_conn->proxy_host ? 124 | (strlen(a_req->host) + 20) : 0)); 125 | memset(l_request, 0, 30 + strlen(a_req->resource) + (a_conn->proxy_host ? 126 | (strlen(a_req->host) + 20) : 0)); 127 | /* copy it into the buffer */ 128 | if (a_conn->proxy_host) 129 | { 130 | l_request_len = sprintf(l_request, 131 | "%s %s HTTP/%01.1f\r\n", 132 | http_req_type_char[a_req->type], 133 | a_req->full_uri, 134 | a_req->http_ver); 135 | } 136 | else 137 | { 138 | l_request_len = sprintf(l_request, 139 | "%s %s HTTP/%01.1f\r\n", 140 | http_req_type_char[a_req->type], 141 | a_req->resource, 142 | a_req->http_ver); 143 | } 144 | /* set the request in the connection buffer */ 145 | http_trans_append_data_to_buf(a_conn, l_request, l_request_len); 146 | /* free up the request - we don't need it anymore */ 147 | free(l_request); 148 | l_request = NULL; 149 | /* set the state */ 150 | a_req->state = http_req_state_sending_request; 151 | http_req_state_sending_request_jump: 152 | /* send the request */ 153 | do { 154 | l_rv = http_trans_write_buf(a_conn); 155 | if ((a_conn->sync == HTTP_TRANS_ASYNC) && (l_rv == HTTP_TRANS_NOT_DONE)) 156 | return HTTP_TRANS_NOT_DONE; 157 | if ((l_rv == HTTP_TRANS_DONE) && (a_conn->last_read == 0)) 158 | return HTTP_TRANS_ERR; 159 | } while (l_rv == HTTP_TRANS_NOT_DONE); 160 | /* reset the buffer */ 161 | http_trans_buf_reset(a_conn); 162 | /* set up all of the headers */ 163 | for (i = 0; i < HTTP_HDRS_MAX; i++) 164 | { 165 | l_len = 0; 166 | if (a_req->headers->header[i]) 167 | { 168 | l_len = strlen(a_req->headers->header[i]); 169 | if (l_len > 0) 170 | { 171 | http_trans_append_data_to_buf(a_conn, a_req->headers->header[i], l_len); 172 | l_headers_len += l_len; 173 | http_trans_append_data_to_buf(a_conn, ": ", 2); 174 | l_headers_len += 2; 175 | /* note, it's ok to have no value for a request */ 176 | if ((l_len = strlen(a_req->headers->value[i])) > 0) 177 | { 178 | http_trans_append_data_to_buf(a_conn, a_req->headers->value[i], l_len); 179 | l_headers_len += l_len; 180 | } 181 | http_trans_append_data_to_buf(a_conn, "\r\n", 2); 182 | l_headers_len += 2; 183 | } 184 | } 185 | } 186 | http_trans_append_data_to_buf(a_conn, "\r\n", 2); 187 | l_headers_len += 2; 188 | /* set the state */ 189 | a_req->state = http_req_state_sending_headers; 190 | http_req_state_sending_headers_jump: 191 | /* blast that out to the network */ 192 | do { 193 | l_rv = http_trans_write_buf(a_conn); 194 | if ((a_conn->sync == HTTP_TRANS_ASYNC) && (l_rv == HTTP_TRANS_NOT_DONE)) 195 | return HTTP_TRANS_NOT_DONE; 196 | if ((l_rv == HTTP_TRANS_DONE) && (a_conn->last_read == 0)) 197 | return HTTP_TRANS_ERR; 198 | } while (l_rv == HTTP_TRANS_NOT_DONE); 199 | /* reset the buffer */ 200 | http_trans_buf_reset(a_conn); 201 | l_content = http_hdr_get_value(a_req->headers, http_hdr_Content_Length); 202 | if (l_content) 203 | { 204 | /* append the information to the buffer */ 205 | http_trans_append_data_to_buf(a_conn, a_req->body, a_req->body_len); 206 | a_req->state = http_req_state_sending_body; 207 | http_req_state_sending_body_jump: 208 | do { 209 | l_rv = http_trans_write_buf(a_conn); 210 | if ((a_conn->sync == HTTP_TRANS_ASYNC) && (l_rv == HTTP_TRANS_NOT_DONE)) 211 | return HTTP_TRANS_NOT_DONE; 212 | if ((l_rv == HTTP_TRANS_DONE) && (a_conn->last_read == 0)) 213 | return HTTP_TRANS_ERR; 214 | } while (l_rv == HTTP_TRANS_NOT_DONE); 215 | /* reset the buffer */ 216 | http_trans_buf_reset(a_conn); 217 | } 218 | return HTTP_TRANS_DONE; 219 | } 220 | -------------------------------------------------------------------------------- /src/liblwqq/libghttp/http_req.h: -------------------------------------------------------------------------------- 1 | /* 2 | * http_req.h -- Routines for setting up an http request 3 | * Created: Christopher Blizzard , 6-Aug-1998 4 | * 5 | * Copyright (C) 1998 Free Software Foundation 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Library General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Library General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Library General Public 18 | * License along with this library; if not, write to the Free 19 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | */ 21 | 22 | /* types of requests */ 23 | 24 | #ifndef HTTP_REQ_H 25 | #define HTTP_REQ_H 26 | 27 | #include 28 | #include "http_hdrs.h" 29 | #include "http_trans.h" 30 | 31 | typedef enum http_req_type { 32 | http_req_type_get = 0, 33 | http_req_type_options, 34 | http_req_type_head, 35 | http_req_type_post, 36 | http_req_type_put, 37 | http_req_type_delete, 38 | http_req_type_trace, 39 | http_req_type_connect, 40 | http_req_type_propfind, 41 | http_req_type_proppatch, 42 | http_req_type_mkcol, 43 | http_req_type_copy, 44 | http_req_type_move, 45 | http_req_type_lock, 46 | http_req_type_unlock 47 | } http_req_type; 48 | 49 | typedef enum http_req_state_tag { 50 | http_req_state_start = 0, 51 | http_req_state_sending_request, 52 | http_req_state_sending_headers, 53 | http_req_state_sending_body 54 | } http_req_state; 55 | 56 | /* same character representations as above. */ 57 | 58 | extern const char *http_req_type_char[]; 59 | 60 | typedef struct http_req_tag { 61 | http_req_type type; 62 | float http_ver; 63 | char *host; 64 | char *full_uri; 65 | char *resource; 66 | char *body; 67 | int body_len; 68 | http_hdr_list *headers; 69 | http_req_state state; 70 | } http_req; 71 | 72 | http_req * 73 | http_req_new(void); 74 | 75 | void 76 | http_req_destroy(http_req *a_req); 77 | 78 | int 79 | http_req_prepare(http_req *a_req); 80 | 81 | int 82 | http_req_send(http_req *a_req, http_trans_conn *a_conn); 83 | 84 | #endif /* HTTP_REQ_H */ 85 | -------------------------------------------------------------------------------- /src/liblwqq/libghttp/http_resp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * http_resp.h -- routines for reading http responses 3 | * Created: Christopher Blizzard 9-Aug-1998 4 | * 5 | * Copyright (C) 1998 Free Software Foundation 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Library General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Library General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Library General Public 18 | * License along with this library; if not, write to the Free 19 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | */ 21 | 22 | #ifndef HTTP_RESP_H 23 | #define HTTP_RESP_H 24 | 25 | #include "http_hdrs.h" 26 | #include "http_trans.h" 27 | #include "http_req.h" 28 | 29 | #define HTTP_RESP_INFORMATIONAL(x) (x >=100 && < 200) 30 | #define HTTP_RESP_SUCCESS(x) (x >= 200 && x < 300) 31 | #define HTTP_RESP_REDIR(x) (x >= 300 && x < 400) 32 | #define HTTP_RESP_CLIENT_ERR(x) (x >= 400 && x < 500) 33 | #define HTTP_RESP_SERVER_ERR(x) (x >= 500 && x < 600) 34 | 35 | typedef enum http_resp_header_state_tag 36 | { 37 | http_resp_header_start = 0, 38 | http_resp_reading_header 39 | } http_resp_header_state; 40 | 41 | typedef enum http_resp_body_state_tag 42 | { 43 | http_resp_body_start = 0, 44 | http_resp_body_read_content_length, 45 | http_resp_body_read_chunked, 46 | http_resp_body_read_standard 47 | } http_resp_body_state; 48 | 49 | 50 | 51 | typedef struct http_resp_tag 52 | { 53 | float http_ver; 54 | int status_code; 55 | char *reason_phrase; 56 | http_hdr_list *headers; 57 | char *body; 58 | int body_len; 59 | int content_length; 60 | int flushed_length; 61 | http_resp_header_state header_state; 62 | http_resp_body_state body_state; 63 | } http_resp; 64 | 65 | http_resp * 66 | http_resp_new(void); 67 | 68 | void 69 | http_resp_destroy(http_resp *a_resp); 70 | 71 | int 72 | http_resp_read_body(http_resp *a_resp, 73 | http_req *a_req, 74 | http_trans_conn *a_conn); 75 | 76 | int 77 | http_resp_read_headers(http_resp *a_resp, http_trans_conn *a_conn); 78 | 79 | void 80 | http_resp_flush(http_resp *a_resp, 81 | http_trans_conn *a_conn); 82 | 83 | #endif /* HTTP_RESP_H */ 84 | -------------------------------------------------------------------------------- /src/liblwqq/libghttp/http_trans.h: -------------------------------------------------------------------------------- 1 | /* 2 | * http_trans.h -- This file contains definitions for http transport functions 3 | * Created: Christopher Blizzard , 5-Aug-1998 4 | * 5 | * Copyright (C) 1998 Free Software Foundation 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Library General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Library General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Library General Public 18 | * License along with this library; if not, write to the Free 19 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | */ 21 | 22 | #ifndef HTTP_TRANS_H 23 | #define HTTP_TRANS_H 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | typedef enum http_trans_err_type_tag { 31 | http_trans_err_type_host = 0, 32 | http_trans_err_type_errno 33 | } http_trans_err_type; 34 | 35 | typedef struct http_trans_conn_tag { 36 | struct hostent *hostinfo; 37 | struct sockaddr_in saddr; 38 | char *host; 39 | char *proxy_host; 40 | int sock; 41 | short port; 42 | short proxy_port; 43 | http_trans_err_type error_type; 44 | int error; 45 | int sync; /* sync or async? */ 46 | char *io_buf; /* buffer */ 47 | int io_buf_len; /* how big is it? */ 48 | int io_buf_alloc; /* how much is used */ 49 | int io_buf_io_done; /* how much have we already moved? */ 50 | int io_buf_io_left; /* how much data do we have left? */ 51 | int io_buf_chunksize; /* how big should the chunks be that get 52 | read in and out be? */ 53 | int last_read; /* the size of the last read */ 54 | int chunk_len; /* length of a chunk. */ 55 | char *errstr; /* a hint as to an error */ 56 | } http_trans_conn; 57 | 58 | http_trans_conn * 59 | http_trans_conn_new(void); 60 | 61 | void 62 | http_trans_conn_destroy(http_trans_conn *a_conn); 63 | 64 | void 65 | http_trans_buf_reset(http_trans_conn *a_conn); 66 | 67 | void 68 | http_trans_buf_clip(http_trans_conn *a_conn, char *a_clip_to); 69 | 70 | int 71 | http_trans_connect(http_trans_conn *a_conn); 72 | 73 | const char * 74 | http_trans_get_host_error(int a_herror); 75 | 76 | int 77 | http_trans_append_data_to_buf(http_trans_conn *a_conn, 78 | char *a_data, 79 | int a_data_len); 80 | 81 | int 82 | http_trans_read_into_buf(http_trans_conn *a_conn); 83 | 84 | int 85 | http_trans_write_buf(http_trans_conn *a_conn); 86 | 87 | char * 88 | http_trans_buf_has_patt(char *a_buf, int a_len, 89 | char *a_pat, int a_patlen); 90 | 91 | #endif /* HTTP_TRANS_H */ 92 | -------------------------------------------------------------------------------- /src/liblwqq/libghttp/http_uri.c: -------------------------------------------------------------------------------- 1 | /* 2 | * http_uri.c --- Contains functions to parse uri's 3 | * Created: Christopher Blizzard , 4-Jul-98 4 | * 5 | * Copyright (C) 1998 Free Software Foundation 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Library General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Library General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Library General Public 18 | * License along with this library; if not, write to the Free 19 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include "http_uri.h" 26 | 27 | typedef enum uri_parse_state_tag 28 | { 29 | parse_state_read_host = 0, 30 | parse_state_read_port, 31 | parse_state_read_resource 32 | } uri_parse_state; 33 | 34 | 35 | int 36 | http_uri_parse(char *a_string, 37 | http_uri *a_uri) 38 | { 39 | /* Everyone chant... "we love state machines..." */ 40 | uri_parse_state l_state = parse_state_read_host; 41 | char *l_start_string = NULL; 42 | char *l_end_string = NULL; 43 | char l_temp_port[6]; 44 | 45 | /* init the array */ 46 | memset(l_temp_port, 0, 6); 47 | /* check the parameters */ 48 | if (a_string == NULL) 49 | goto ec; 50 | if (a_uri) { 51 | a_uri->full = strdup(a_string); 52 | } 53 | l_start_string = strchr(a_string, ':'); 54 | /* check to make sure that there was a : in the string */ 55 | if (!l_start_string) 56 | goto ec; 57 | if (a_uri) { 58 | a_uri->proto = (char *)malloc(l_start_string - a_string + 1); 59 | memcpy(a_uri->proto, a_string, (l_start_string - a_string)); 60 | a_uri->proto[l_start_string - a_string] = '\0'; 61 | } 62 | /* check to make sure it starts with "http://" */ 63 | if (strncmp(l_start_string, "://", 3) != 0) 64 | goto ec; 65 | /* start at the beginning of the string */ 66 | l_start_string = l_end_string = &l_start_string[3]; 67 | while(*l_end_string) 68 | { 69 | if (l_state == parse_state_read_host) 70 | { 71 | if (*l_end_string == ':') 72 | { 73 | l_state = parse_state_read_port; 74 | if ((l_end_string - l_start_string) == 0) 75 | goto ec; 76 | /* allocate space */ 77 | if ((l_end_string - l_start_string) == 0) 78 | goto ec; 79 | /* only do this if a uri was passed in */ 80 | if (a_uri) 81 | { 82 | a_uri->host = (char *)malloc(l_end_string - l_start_string + 1); 83 | /* copy the data */ 84 | memcpy(a_uri->host, l_start_string, (l_end_string - l_start_string)); 85 | /* terminate */ 86 | a_uri->host[l_end_string - l_start_string] = '\0'; 87 | } 88 | /* reset the counters */ 89 | l_end_string++; 90 | l_start_string = l_end_string; 91 | continue; 92 | } 93 | else if (*l_end_string == '/') 94 | { 95 | l_state = parse_state_read_resource; 96 | if ((l_end_string - l_start_string) == 0) 97 | goto ec; 98 | if (a_uri) 99 | { 100 | a_uri->host = (char *)malloc(l_end_string - l_start_string + 1); 101 | memcpy(a_uri->host, l_start_string, (l_end_string - l_start_string)); 102 | a_uri->host[l_end_string - l_start_string] = '\0'; 103 | } 104 | l_start_string = l_end_string; 105 | continue; 106 | } 107 | } 108 | else if (l_state == parse_state_read_port) 109 | { 110 | if (*l_end_string == '/') 111 | { 112 | l_state = parse_state_read_resource; 113 | /* check to make sure we're not going to overflow */ 114 | if (l_end_string - l_start_string > 5) 115 | goto ec; 116 | /* check to make sure there was a port */ 117 | if ((l_end_string - l_start_string) == 0) 118 | goto ec; 119 | /* copy the port into a temp buffer */ 120 | memcpy(l_temp_port, l_start_string, l_end_string - l_start_string); 121 | /* convert it. */ 122 | if (a_uri) 123 | a_uri->port = atoi(l_temp_port); 124 | l_start_string = l_end_string; 125 | continue; 126 | } 127 | else if (isdigit(*l_end_string) == 0) 128 | { 129 | /* check to make sure they are just digits */ 130 | goto ec; 131 | } 132 | } 133 | /* next.. */ 134 | l_end_string++; 135 | continue; 136 | } 137 | 138 | if (l_state == parse_state_read_host) 139 | { 140 | if ((l_end_string - l_start_string) == 0) 141 | goto ec; 142 | if (a_uri) 143 | { 144 | a_uri->host = (char *)malloc(l_end_string - l_start_string + 1); 145 | memcpy(a_uri->host, l_start_string, (l_end_string - l_start_string)); 146 | a_uri->host[l_end_string - l_start_string] = '\0'; 147 | /* for a "/" */ 148 | a_uri->resource = strdup("/"); 149 | } 150 | } 151 | else if (l_state == parse_state_read_port) 152 | { 153 | if (strlen(l_start_string) == 0) 154 | /* oops. that's not a valid number */ 155 | goto ec; 156 | if (a_uri) 157 | { 158 | a_uri->port = atoi(l_start_string); 159 | a_uri->resource = strdup("/"); 160 | } 161 | } 162 | else if (l_state == parse_state_read_resource) 163 | { 164 | if (strlen(l_start_string) == 0) 165 | { 166 | if (a_uri) 167 | a_uri->resource = strdup("/"); 168 | } 169 | else 170 | { 171 | if (a_uri) 172 | a_uri->resource = strdup(l_start_string); 173 | } 174 | } 175 | else 176 | { 177 | /* uhh...how did we get here? */ 178 | goto ec; 179 | } 180 | return 0; 181 | 182 | ec: 183 | return -1; 184 | } 185 | 186 | http_uri * 187 | http_uri_new(void) 188 | { 189 | http_uri *l_return = NULL; 190 | 191 | l_return = (http_uri *)malloc(sizeof(http_uri)); 192 | l_return->full = NULL; 193 | l_return->proto = NULL; 194 | l_return->host = NULL; 195 | l_return->port = 80; 196 | l_return->resource = NULL; 197 | return l_return; 198 | } 199 | 200 | void 201 | http_uri_destroy(http_uri *a_uri) 202 | { 203 | if (a_uri->full) { 204 | free(a_uri->full); 205 | a_uri->full = NULL; 206 | } 207 | if (a_uri->proto) { 208 | free(a_uri->proto); 209 | a_uri->proto = NULL; 210 | } 211 | if (a_uri->host) { 212 | free(a_uri->host); 213 | a_uri->host = NULL; 214 | } 215 | if (a_uri->resource) { 216 | free(a_uri->resource); 217 | a_uri->resource = NULL; 218 | } 219 | free(a_uri); 220 | } 221 | 222 | 223 | -------------------------------------------------------------------------------- /src/liblwqq/libghttp/http_uri.h: -------------------------------------------------------------------------------- 1 | /* 2 | * http_uri.h --- Contains routines for working with uri's 3 | * Created: Christopher Blizzard , 9-Jul-98 4 | * 5 | * Copyright (C) 1998 Free Software Foundation 6 | * 7 | * This library is free software; you can redistribute it and/or 8 | * modify it under the terms of the GNU Library General Public 9 | * License as published by the Free Software Foundation; either 10 | * version 2 of the License, or (at your option) any later version. 11 | * 12 | * This library is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * Library General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU Library General Public 18 | * License along with this library; if not, write to the Free 19 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 | */ 21 | 22 | #ifndef HTTP_URI_H 23 | #define HTTP_URI_H 24 | 25 | /* strings that are used all over the place */ 26 | 27 | typedef struct http_uri_tag 28 | { 29 | char *full; /* full URL */ 30 | char *proto; /* protocol */ 31 | char *host; /* copy semantics */ 32 | unsigned short port; 33 | char *resource; /* copy semantics */ 34 | } http_uri; 35 | 36 | http_uri * 37 | http_uri_new(void); 38 | 39 | void 40 | http_uri_destroy(http_uri *a_uri); 41 | 42 | int 43 | http_uri_parse(char *a_uri, 44 | http_uri *a_request); 45 | 46 | #endif 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/liblwqq/logger.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file logger.c 3 | * @author mathslinux 4 | * @date Sun May 20 23:25:33 2012 5 | * 6 | * @brief Linux WebQQ Logger API 7 | * 8 | * 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include "logger.h" 18 | 19 | static char *levels[] = { 20 | "DEBUG", 21 | "NOTICE", 22 | "WARNING", 23 | "ERROR", 24 | }; 25 | 26 | /** 27 | * This is standard logger function 28 | * 29 | * @param level Which level of this message, e.g. debug 30 | * @param file Which file this function called in 31 | * @param line Which line this function call at 32 | * @param function Which function call this function 33 | * @param msg Log message 34 | */ 35 | void lwqq_log(int level, const char *file, int line, 36 | const char *function, const char* msg, ...) 37 | { 38 | char buf[1600] = {0}; 39 | va_list va; 40 | time_t t = time(NULL); 41 | struct tm *tm; 42 | int buf_used = 0; 43 | char date[256]; 44 | 45 | tm = localtime(&t); 46 | strftime(date, sizeof(date), "%b %e %T", tm); 47 | 48 | snprintf(buf, sizeof(buf), "[%s] %s[%ld]: %s:%d %s: ", date, levels[level], (long)getpid(), file, line, function); 49 | buf_used = strlen(buf); 50 | va_start (va, msg); 51 | vsnprintf(buf + buf_used , sizeof(buf) - buf_used, (char*)msg, va); 52 | va_end(va); 53 | 54 | fprintf(stdout, "%s", buf); 55 | } 56 | -------------------------------------------------------------------------------- /src/liblwqq/md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | * luau (Lib Update/Auto-Update): Simple Update Library 3 | * Copyright (C) 2003 David Eklund 4 | * 5 | * - This library is free software; you can redistribute it and/or - 6 | * - modify it under the terms of the GNU Lesser General Public - 7 | * - License as published by the Free Software Foundation; either - 8 | * - version 2.1 of the License, or (at your option) any later version. - 9 | * - - 10 | * - This library is distributed in the hope that it will be useful, - 11 | * - but WITHOUT ANY WARRANTY; without even the implied warranty of - 12 | * - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - 13 | * - Lesser General Public License for more details. - 14 | * - - 15 | * - You should have received a copy of the GNU Lesser General Public - 16 | * - License along with this library; if not, write to the Free Software - 17 | * - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - 18 | */ 19 | 20 | /* 21 | * md5.h and md5.c are based off of md5hl.c, md5c.c, and md5.h from libmd, which in turn are 22 | * based off the FreeBSD libmd library. Their respective copyright notices follow: 23 | */ 24 | 25 | /* 26 | * This code implements the MD5 message-digest algorithm. 27 | * The algorithm is due to Ron Rivest. This code was 28 | * written by Colin Plumb in 1993, no copyright is claimed. 29 | * This code is in the public domain; do with it what you wish. 30 | * 31 | * Equivalent code is available from RSA Data Security, Inc. 32 | * This code has been tested against that, and is equivalent, 33 | * except that you don't need to include two pages of legalese 34 | * with every copy. 35 | */ 36 | 37 | /* ---------------------------------------------------------------------------- 38 | * "THE BEER-WARE LICENSE" (Revision 42): 39 | * wrote this file. As long as you retain this notice you 40 | * can do whatever you want with this stuff. If we meet some day, and you think 41 | * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 42 | * ---------------------------------------------------------------------------- 43 | * 44 | * $Id: md5.h,v 1.1.1.1 2004/04/02 05:11:38 deklund2 Exp $ 45 | * 46 | */ 47 | 48 | #ifndef MD5_H 49 | #define MD5_H 50 | 51 | #ifdef HAVE_CONFIG_H 52 | # include 53 | #endif 54 | 55 | #include 56 | 57 | #define MD5_HASHBYTES 16 58 | 59 | typedef struct MD5Context { 60 | u_int32_t buf[4]; 61 | u_int32_t bits[2]; 62 | unsigned char in[64]; 63 | } MD5_CTX; 64 | 65 | char* lutil_md5_file(const char *filename, char *buf); 66 | char * lutil_md5_digest(const unsigned char * data, unsigned int len , char *buf); 67 | char* lutil_md5_data(const unsigned char *data, unsigned int len, char *buf); 68 | 69 | #endif /* MD5_H */ 70 | -------------------------------------------------------------------------------- /src/liblwqq/smemory.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file smemory.c 3 | * @author mathslinux 4 | * @date Tue May 22 00:41:24 2012 5 | * 6 | * @brief Small Memory Wrapper 7 | * 8 | * 9 | */ 10 | 11 | #define _GNU_SOURCE 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | void *s_malloc(size_t size) 18 | { 19 | if(size == 0) 20 | return NULL; 21 | 22 | return malloc(size); 23 | } 24 | 25 | void *s_malloc0(size_t size) 26 | { 27 | if (size == 0) 28 | return NULL; 29 | 30 | void *ptr = malloc(size); 31 | if (ptr) 32 | memset(ptr, 0, size); 33 | 34 | return ptr; 35 | } 36 | 37 | void *s_calloc(size_t nmemb, size_t lsize) 38 | { 39 | return calloc(nmemb, lsize); 40 | } 41 | 42 | void *s_realloc(void *ptr, size_t size) 43 | { 44 | return realloc(ptr, size); 45 | } 46 | 47 | void s_free(void *ptr) 48 | { 49 | if (ptr) 50 | free(ptr); 51 | } 52 | 53 | char *s_strdup(const char *s1) 54 | { 55 | if (!s1) 56 | return NULL; 57 | 58 | return strdup(s1); 59 | } 60 | 61 | char *s_strndup(const char *s1, size_t n) 62 | { 63 | if (!s1) 64 | return NULL; 65 | 66 | return strndup(s1, n); 67 | } 68 | 69 | int s_vasprintf(char **buf, const char * format, 70 | va_list arg) 71 | { 72 | return vasprintf(buf, format, arg); 73 | } 74 | 75 | int s_asprintf(char **buf, const char *format, ...) 76 | { 77 | va_list arg; 78 | int rv; 79 | 80 | va_start(arg, format); 81 | rv = s_vasprintf(buf, format, arg); 82 | va_end(arg); 83 | 84 | return rv; 85 | } 86 | -------------------------------------------------------------------------------- /src/liblwqq/type.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file type.c 3 | * @author mathslinux 4 | * @date Sun May 20 23:01:57 2012 5 | * 6 | * @brief Linux WebQQ Data Struct API 7 | * 8 | * 9 | */ 10 | 11 | #include 12 | #include 13 | #include "type.h" 14 | #include "smemory.h" 15 | #include "logger.h" 16 | #include "msg.h" 17 | 18 | /** 19 | * Create a new lwqq client 20 | * 21 | * @param username QQ username 22 | * @param password QQ password 23 | * 24 | * @return A new LwqqClient instance, or NULL failed 25 | */ 26 | LwqqClient *lwqq_client_new(const char *username, const char *password) 27 | { 28 | struct timeval tv; 29 | long v; 30 | 31 | if (!username || !password) { 32 | lwqq_log(LOG_ERROR, "Username or password is null\n"); 33 | return NULL; 34 | } 35 | 36 | LwqqClient *lc = s_malloc0(sizeof(*lc)); 37 | lc->username = s_strdup(username); 38 | lc->password = s_strdup(password); 39 | lc->myself = lwqq_buddy_new(); 40 | if (!lc->myself) { 41 | goto failed; 42 | } 43 | lc->myself->qqnumber = s_strdup(username); 44 | lc->myself->uin = s_strdup(username); 45 | 46 | lc->cookies = s_malloc0(sizeof(*(lc->cookies))); 47 | 48 | lc->msg_list = lwqq_recvmsg_new(lc); 49 | 50 | /* Set msg_id */ 51 | gettimeofday(&tv, NULL); 52 | v = tv.tv_usec; 53 | v = (v - v % 1000) / 1000; 54 | v = v % 10000 * 10000; 55 | lc->msg_id = v; 56 | 57 | lwqq_log(LOG_DEBUG, "Create a new client with username:%s, password:%s " 58 | "successfully\n", lc->username, lc->password); 59 | return lc; 60 | 61 | failed: 62 | lwqq_client_free(lc); 63 | return NULL; 64 | } 65 | 66 | /** 67 | * Get cookies needby by webqq server 68 | * 69 | * @param lc 70 | * 71 | * @return Cookies string on success, or null on failure 72 | */ 73 | char *lwqq_get_cookies(LwqqClient *lc) 74 | { 75 | if (lc->cookies && lc->cookies->lwcookies) { 76 | return s_strdup(lc->cookies->lwcookies); 77 | } 78 | 79 | return NULL; 80 | } 81 | 82 | void lwqq_vc_free(LwqqVerifyCode *vc) 83 | { 84 | if (vc) { 85 | s_free(vc->str); 86 | s_free(vc->type); 87 | s_free(vc->img); 88 | s_free(vc->uin); 89 | s_free(vc); 90 | } 91 | } 92 | 93 | static void cookies_free(LwqqCookies *c) 94 | { 95 | if (c) { 96 | s_free(c->ptvfsession); 97 | s_free(c->ptcz); 98 | s_free(c->skey); 99 | s_free(c->ptwebqq); 100 | s_free(c->ptuserinfo); 101 | s_free(c->uin); 102 | s_free(c->ptisp); 103 | s_free(c->pt2gguin); 104 | s_free(c->verifysession); 105 | s_free(c->lwcookies); 106 | s_free(c); 107 | } 108 | } 109 | 110 | static void lwqq_categories_free(LwqqFriendCategory *cate) 111 | { 112 | if (!cate) 113 | return ; 114 | 115 | s_free(cate->name); 116 | s_free(cate); 117 | } 118 | 119 | /** 120 | * Free LwqqClient instance 121 | * 122 | * @param client LwqqClient instance 123 | */ 124 | void lwqq_client_free(LwqqClient *client) 125 | { 126 | LwqqBuddy *b_entry, *b_next; 127 | LwqqFriendCategory *c_entry, *c_next; 128 | LwqqGroup *g_entry, *g_next; 129 | 130 | if (!client) 131 | return ; 132 | 133 | /* Free LwqqVerifyCode instance */ 134 | s_free(client->username); 135 | s_free(client->password); 136 | s_free(client->version); 137 | lwqq_vc_free(client->vc); 138 | cookies_free(client->cookies); 139 | s_free(client->clientid); 140 | s_free(client->seskey); 141 | s_free(client->cip); 142 | s_free(client->index); 143 | s_free(client->port); 144 | s_free(client->status); 145 | s_free(client->vfwebqq); 146 | s_free(client->psessionid); 147 | lwqq_buddy_free(client->myself); 148 | 149 | /* Free friends list */ 150 | LIST_FOREACH_SAFE(b_entry, &client->friends, entries, b_next) { 151 | LIST_REMOVE(b_entry, entries); 152 | lwqq_buddy_free(b_entry); 153 | } 154 | 155 | /* Free categories list */ 156 | LIST_FOREACH_SAFE(c_entry, &client->categories, entries, c_next) { 157 | LIST_REMOVE(c_entry, entries); 158 | lwqq_categories_free(c_entry); 159 | } 160 | 161 | 162 | /* Free groups list */ 163 | LIST_FOREACH_SAFE(g_entry, &client->groups, entries, g_next) { 164 | LIST_REMOVE(g_entry, entries); 165 | lwqq_group_free(g_entry); 166 | } 167 | 168 | /* Free msg_list */ 169 | lwqq_recvmsg_free(client->msg_list); 170 | s_free(client); 171 | } 172 | 173 | /************************************************************************/ 174 | /* LwqqBuddy API */ 175 | 176 | /** 177 | * 178 | * Create a new buddy 179 | * 180 | * @return A LwqqBuddy instance 181 | */ 182 | LwqqBuddy *lwqq_buddy_new() 183 | { 184 | LwqqBuddy *b = s_malloc0(sizeof(*b)); 185 | return b; 186 | } 187 | 188 | /** 189 | * Free a LwqqBuddy instance 190 | * 191 | * @param buddy 192 | */ 193 | void lwqq_buddy_free(LwqqBuddy *buddy) 194 | { 195 | if (!buddy) 196 | return ; 197 | 198 | s_free(buddy->uin); 199 | s_free(buddy->qqnumber); 200 | s_free(buddy->face); 201 | s_free(buddy->occupation); 202 | s_free(buddy->phone); 203 | s_free(buddy->allow); 204 | s_free(buddy->college); 205 | s_free(buddy->reg_time); 206 | s_free(buddy->constel); 207 | s_free(buddy->blood); 208 | s_free(buddy->homepage); 209 | s_free(buddy->stat); 210 | s_free(buddy->country); 211 | s_free(buddy->city); 212 | s_free(buddy->personal); 213 | s_free(buddy->nick); 214 | s_free(buddy->long_nick); 215 | s_free(buddy->shengxiao); 216 | s_free(buddy->email); 217 | s_free(buddy->province); 218 | s_free(buddy->gender); 219 | s_free(buddy->mobile); 220 | s_free(buddy->vip_info); 221 | s_free(buddy->markname); 222 | s_free(buddy->flag); 223 | s_free(buddy->cate_index); 224 | s_free(buddy->client_type); 225 | 226 | s_free(buddy->status); 227 | 228 | s_free(buddy); 229 | } 230 | 231 | /** 232 | * Find buddy object by buddy's uin member 233 | * 234 | * @param lc Our Lwqq client object 235 | * @param uin The uin of buddy which we want to find 236 | * 237 | * @return 238 | */ 239 | LwqqBuddy *lwqq_buddy_find_buddy_by_uin(LwqqClient *lc, const char *uin) 240 | { 241 | LwqqBuddy *buddy; 242 | 243 | if (!lc || !uin) 244 | return NULL; 245 | 246 | LIST_FOREACH(buddy, &lc->friends, entries) { 247 | if (buddy->uin && (strcmp(buddy->uin, uin) == 0)) 248 | return buddy; 249 | } 250 | 251 | return NULL; 252 | } 253 | 254 | /* LwqqBuddy API END*/ 255 | /************************************************************************/ 256 | 257 | /** 258 | * Create a new group 259 | * 260 | * @return A LwqqGroup instance 261 | */ 262 | LwqqGroup *lwqq_group_new() 263 | { 264 | LwqqGroup *g = s_malloc0(sizeof(*g)); 265 | return g; 266 | } 267 | 268 | /** 269 | * Free a LwqqGroup instance 270 | * 271 | * @param group 272 | */ 273 | void lwqq_group_free(LwqqGroup *group) 274 | { 275 | LwqqBuddy *m_entry, *m_next; 276 | if (!group) 277 | return ; 278 | 279 | s_free(group->name); 280 | s_free(group->gid); 281 | s_free(group->code); 282 | s_free(group->account); 283 | s_free(group->markname); 284 | s_free(group->face); 285 | s_free(group->memo); 286 | s_free(group->class); 287 | s_free(group->fingermemo); 288 | s_free(group->createtime); 289 | s_free(group->level); 290 | s_free(group->owner); 291 | s_free(group->flag); 292 | s_free(group->option); 293 | 294 | /* Free Group members list */ 295 | LIST_FOREACH_SAFE(m_entry, &group->members, entries, m_next) { 296 | LIST_REMOVE(m_entry, entries); 297 | lwqq_buddy_free(m_entry); 298 | } 299 | 300 | s_free(group); 301 | } 302 | 303 | 304 | /** 305 | * Find group object by group's gid member 306 | * 307 | * @param lc Our Lwqq client object 308 | * @param uin The gid of group which we want to find 309 | * 310 | * @return A LwqqGroup instance 311 | */ 312 | LwqqGroup *lwqq_group_find_group_by_gid(LwqqClient *lc, const char *gid) 313 | { 314 | LwqqGroup *group; 315 | 316 | if (!lc || !gid) 317 | return NULL; 318 | 319 | LIST_FOREACH(group, &lc->groups, entries) { 320 | if (group->gid && (strcmp(group->gid, gid) == 0)) 321 | return group; 322 | } 323 | 324 | return NULL; 325 | } 326 | 327 | /** 328 | * Find group member object by member's uin 329 | * 330 | * @param group Our Lwqq group object 331 | * @param uin The uin of group member which we want to find 332 | * 333 | * @return A LwqqBuddy instance 334 | */ 335 | LwqqBuddy *lwqq_group_find_group_member_by_uin(LwqqGroup *group, const char *uin) 336 | { 337 | LwqqBuddy *member; 338 | 339 | if (!group || !uin) 340 | return NULL; 341 | 342 | LIST_FOREACH(member, &group->members, entries) { 343 | if (member->uin && (strcmp(member->uin, uin) == 0)) 344 | return member; 345 | } 346 | 347 | return NULL; 348 | } 349 | -------------------------------------------------------------------------------- /src/liblwqq/unicode.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file unicode.c 3 | * @author mathslinux 4 | * @date Mon Jun 18 23:03:31 2012 5 | * 6 | * @brief ucs to utf-8, this file is written by kernelhcy in gtkqq 7 | * i rewrite to undependent glib 8 | * 9 | * 10 | */ 11 | 12 | #include 13 | #include 14 | #include "smemory.h" 15 | 16 | static unsigned int hex2char(char c) 17 | { 18 | if (c >= '0' && c <= '9') { 19 | return c - '0'; 20 | } 21 | 22 | if (c >= 'a' && c <= 'f') { 23 | return c - 'a' + 10; 24 | } 25 | 26 | if (c >= 'A' && c <= 'F') { 27 | return c - 'A' + 10; 28 | } 29 | 30 | return 0; 31 | } 32 | 33 | /** 34 | * decode UCS-4 to utf8 35 | * UCS-4 code UTF-8 36 | * U+00000000–U+0000007F 0xxxxxxx 37 | * U+00000080–U+000007FF 110xxxxx 10xxxxxx 38 | * U+00000800–U+0000FFFF 1110xxxx 10xxxxxx 10xxxxxx 39 | * U+00010000–U+001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 40 | * U+00200000–U+03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 41 | * U+04000000–U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 42 | * 43 | * Chinese are all in U+00000800–U+0000FFFF. 44 | * So only decode to the second and third format. 45 | * 46 | * @param to 47 | * @param from 48 | */ 49 | static char *do_ucs4toutf8(const char *from) 50 | { 51 | char str[5] = {0}; 52 | int i; 53 | 54 | static unsigned int E = 0xe0; 55 | static unsigned int T = 0x02; 56 | static unsigned int sep1 = 0x80; 57 | static unsigned int sep2 = 0x800; 58 | static unsigned int sep3 = 0x10000; 59 | static unsigned int sep4 = 0x200000; 60 | static unsigned int sep5 = 0x4000000; 61 | 62 | unsigned int tmp[4]; 63 | char re[6]; 64 | unsigned int ivalue = 0; 65 | 66 | for (i = 0; i < 4; ++i) { 67 | tmp[i] = 0xf & hex2char(from[i + 2]); 68 | ivalue *= 16; 69 | ivalue += tmp[i]; 70 | } 71 | 72 | /* decode */ 73 | if (ivalue < sep1) { 74 | /* 0xxxxxxx */ 75 | re[0] = 0x7f & tmp[3]; 76 | str[0] = re[0]; 77 | } else if (ivalue < sep2) { 78 | /* 110xxxxx 10xxxxxx */ 79 | re[0] = (0x3 << 6) | ((tmp[1] & 7) << 2) | (tmp[2] >> 2); 80 | re[1] = (0x1 << 7) | ((tmp[2] & 3) << 4) | tmp[3]; 81 | str[0] = re[0]; 82 | str[1] = re[1]; 83 | } else if (ivalue < sep3) { 84 | /* 1110xxxx 10xxxxxx 10xxxxxx */ 85 | re[0] = E | (tmp[0] & 0xf); 86 | re[1] = (T << 6) | (tmp[1] << 2) | ((tmp[2] >> 2) & 0x3); 87 | re[2] = (T << 6) | (tmp[2] & 0x3) << 4 | tmp[3]; 88 | /* copy to @to. */ 89 | for (i = 0; i < 3; ++i){ 90 | str[i] = re[i]; 91 | } 92 | } else if (ivalue < sep4) { 93 | /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ 94 | re[0] = 0xf0 | ((tmp[1] >> 2) & 0x7); 95 | re[1] = 0x2 << 6 | ((tmp[1] & 0x3) << 4) | ((tmp[2] >> 4) & 0xf); 96 | re[2] = 0x2 << 6 | ((tmp[2] & 0xf) << 4) | ((tmp[3] >> 6) & 0x3); 97 | re[3] = 0x2 << 6 | (tmp[2] & 0x3f); 98 | /* copy to @to. */ 99 | for (i = 0; i < 4; ++i) { 100 | str[i] = re[i]; 101 | } 102 | } else if (ivalue < sep5) { 103 | /* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ 104 | return NULL; 105 | } else { 106 | /* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx */ 107 | return NULL; 108 | } 109 | 110 | return s_strdup(str); 111 | } 112 | 113 | char *ucs4toutf8(const char *from) 114 | { 115 | if (!from) { 116 | return NULL; 117 | } 118 | 119 | char *out = NULL; 120 | int outlen = 0; 121 | const char *c; 122 | 123 | for (c = from; *c != '\0'; ++c) { 124 | char *s; 125 | if (*c == '\\' && *(c + 1) == 'u') { 126 | s = do_ucs4toutf8(c); 127 | out = s_realloc(out, outlen + strlen(s) + 1); 128 | snprintf(out + outlen, strlen(s) + 1, "%s", s); 129 | outlen = strlen(out); 130 | s_free(s); 131 | c += 5; 132 | } else { 133 | out = s_realloc(out, outlen + 2); 134 | out[outlen] = *c; 135 | out[outlen + 1] = '\0'; 136 | outlen++; 137 | continue; 138 | } 139 | } 140 | 141 | return out; 142 | } 143 | -------------------------------------------------------------------------------- /src/liblwqq/unicode.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file unicode.c 3 | * @author mathslinux 4 | * @date Mon Jun 18 23:03:31 2012 5 | * 6 | * @brief ucs to utf-8, this file is written by kernelhcy in gtkqq 7 | * i rewrite to undependent glib 8 | * 9 | * 10 | */ 11 | 12 | #ifndef LWQQ_UNICODE_H 13 | #define LWQQ_UNICODE_H 14 | 15 | char *ucs4toutf8(const char *from); 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/liblwqq/url.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file test.c 3 | * @author mathslinux 4 | * @date Thu May 24 22:56:52 2012 5 | * 6 | * @brief The Encode and Decode helper is based on 7 | * code where i download from http://www.geekhideout.com/urlcode.shtml 8 | * 9 | * 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | /* Converts a hex character to its integer value */ 16 | static char from_hex(char ch) 17 | { 18 | return isdigit(ch) ? ch - '0' : tolower(ch) - 'A' + 10; 19 | } 20 | 21 | /* Converts an integer value to its hex character*/ 22 | static char to_hex(char code) 23 | { 24 | static char hex[] = "0123456789ABCDEF"; 25 | return hex[code & 15]; 26 | } 27 | 28 | /** 29 | * NB: be sure to free() the returned string after use 30 | * 31 | * @param str 32 | * 33 | * @return A url-encoded version of str 34 | */ 35 | char *url_encode(char *str) 36 | { 37 | if (!str) 38 | return NULL; 39 | 40 | char *pstr = str, *buf = malloc(strlen(str) * 3 + 1), *pbuf = buf; 41 | while (*pstr) { 42 | if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~') 43 | *pbuf++ = *pstr; 44 | else 45 | *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15); 46 | pstr++; 47 | } 48 | *pbuf = '\0'; 49 | return buf; 50 | } 51 | 52 | /** 53 | * NB: be sure to free() the returned string after use 54 | * 55 | * @param str 56 | * 57 | * @return A url-decoded version of str 58 | */ 59 | char *url_decode(char *str) 60 | { 61 | if (!str) { 62 | return NULL; 63 | } 64 | char *pstr = str, *buf = malloc(strlen(str) + 1), *pbuf = buf; 65 | while (*pstr) { 66 | if (*pstr == '%') { 67 | if (pstr[1] && pstr[2]) { 68 | *pbuf++ = from_hex(pstr[1]) << 4 | from_hex(pstr[2]); 69 | pstr += 2; 70 | } 71 | } else if (*pstr == '+') { 72 | *pbuf++ = ' '; 73 | } else { 74 | *pbuf++ = *pstr; 75 | } 76 | pstr++; 77 | } 78 | *pbuf = '\0'; 79 | return buf; 80 | } 81 | 82 | #if 0 83 | int main(int argc, char *argv[]) 84 | { 85 | char *buf = url_encode("http://www.-go8ogle. com"); 86 | if (buf) { 87 | lwqq_log(LOG_NOTICE, "Encode data: %s\n", buf); 88 | } else 89 | puts(buf); 90 | return 0; 91 | } 92 | #endif 93 | -------------------------------------------------------------------------------- /src/liblwqq/url.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file url.h 3 | * @author mathslinux 4 | * @date Thu May 24 23:01:23 2012 5 | * 6 | * @brief The Encode and Decode helper is based on 7 | * code where i download from http://www.geekhideout.com/urlcode.shtml 8 | * 9 | * 10 | */ 11 | 12 | #ifndef LWQQ_URL_H 13 | #define LWQQ_URL_H 14 | 15 | /** 16 | * NB: be sure to free() the returned string after use 17 | * 18 | * @param str 19 | * 20 | * @return A url-encoded version of str 21 | */ 22 | char *url_encode(char *str); 23 | 24 | /** 25 | * NB: be sure to free() the returned string after use 26 | * 27 | * @param str 28 | * 29 | * @return A url-decoded version of str 30 | */ 31 | char *url_decode(char *str); 32 | 33 | #endif /* LWQQ_URL_H */ 34 | -------------------------------------------------------------------------------- /src/lwdb/Makefile.am: -------------------------------------------------------------------------------- 1 | lib_LTLIBRARIES=liblwdb.la 2 | liblwdb_la_CPPFLAGS=-I../include/lwqq ${SQLITE3_CFLAGS} 3 | liblwdb_la_LIBADD= ${SQLITE3_LIBS} 4 | liblwdb_la_SOURCES=lwdb.c lwdb.h swsqlite.c swsqlite.h 5 | AM_CFLAGS = 6 | 7 | -------------------------------------------------------------------------------- /src/lwdb/lwdb.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file lwdb.c 3 | * @author mathslinux 4 | * @date Tue May 29 15:24:42 2012 5 | * 6 | * @brief LWQQ Datebase API 7 | * We use Sqlite3 in this project 8 | * 9 | * 10 | */ 11 | 12 | #ifndef LWDB_H 13 | #define LWDB_H 14 | 15 | #include "type.h" 16 | #include "swsqlite.h" 17 | 18 | /************************************************************************/ 19 | /* Initialization and final API */ 20 | /** 21 | * LWDB initialization 22 | * 23 | */ 24 | void lwdb_init(); 25 | 26 | /** 27 | * LWDB final 28 | * 29 | */ 30 | void lwdb_finalize(); 31 | 32 | /* Initialization and final API end */ 33 | 34 | /************************************************************************/ 35 | /* LwdbGlobalDB API */ 36 | typedef struct LwdbGlobalUserEntry { 37 | char *qqnumber; 38 | char *db_name; 39 | char *password; 40 | char *status; 41 | char *rempwd; 42 | LIST_ENTRY(LwdbGlobalUserEntry) entries; 43 | } LwdbGlobalUserEntry; 44 | 45 | typedef struct LwdbGlobalDB { 46 | SwsDB *db; /**< Pointer sqlite3 db */ 47 | LwqqErrorCode (*add_new_user)(struct LwdbGlobalDB *db, const char *qqnumber); 48 | LwdbGlobalUserEntry * (*query_user_info)(struct LwdbGlobalDB *db, 49 | const char *qqnumber); 50 | LIST_HEAD(, LwdbGlobalUserEntry) head; /**< QQ friends */ 51 | LwqqErrorCode (*update_user_info)(struct LwdbGlobalDB *db, const char *qqnumber, 52 | const char *key, const char *value); 53 | } LwdbGlobalDB; 54 | 55 | /** 56 | * Create a global DB object 57 | * 58 | * @return A new global DB object, or NULL if somethins wrong, and store 59 | * error code in err 60 | */ 61 | LwdbGlobalDB *lwdb_globaldb_new(void); 62 | 63 | /** 64 | * Free a LwdbGlobalDb object 65 | * 66 | * @param db 67 | */ 68 | void lwdb_globaldb_free(LwdbGlobalDB *db); 69 | 70 | /** 71 | * Free LwdbGlobalUserEntry object 72 | * 73 | * @param e 74 | */ 75 | void lwdb_globaldb_free_user_entry(LwdbGlobalUserEntry *e); 76 | 77 | /* LwdbGlobalDB API end */ 78 | 79 | /************************************************************************/ 80 | /* LwdbUserDB API */ 81 | 82 | typedef struct LwdbUserDB { 83 | SwsDB *db; 84 | LwqqBuddy * (*query_buddy_info)(struct LwdbUserDB *db, const char *qqnumber); 85 | LwqqErrorCode (*update_buddy_info)(struct LwdbUserDB *db, LwqqBuddy *buddy); 86 | } LwdbUserDB; 87 | /** 88 | * Create a user DB object 89 | * 90 | * @param qqnumber The qq number 91 | * 92 | * @return A new user DB object, or NULL if somethins wrong, and store 93 | * error code in err 94 | */ 95 | LwdbUserDB *lwdb_userdb_new(const char *qqnumber); 96 | 97 | /** 98 | * Free a LwdbUserDB object 99 | * 100 | * @param db 101 | */ 102 | void lwdb_userdb_free(LwdbUserDB *db); 103 | 104 | /* LwdbUserDB API end */ 105 | 106 | /************************************************************************/ 107 | 108 | #endif 109 | -------------------------------------------------------------------------------- /src/lwdb/swsqlite.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file swsqlite.c 3 | * @author mathslinux 4 | * @date Wed May 30 10:36:42 2012 5 | * 6 | * @brief Simple wrapper of sqlite 7 | * 8 | * 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include "swsqlite.h" 15 | 16 | #define SET_ERRMSG(a, msg) if(a) *a = strdup(msg) 17 | 18 | 19 | /** 20 | * Open a sqlite3 database 21 | * 22 | * @param filename DB filename 23 | * @param errmsg If open db failed, a error information will be stored in 24 | * errmsg if you pass this parameterment. 25 | * 26 | * @return A new SwsDB object, or NULL if something error happens 27 | */ 28 | SwsDB *sws_open_db(const char *filename, char **errmsg) 29 | { 30 | int ret; 31 | sqlite3 *db = NULL; 32 | 33 | if (!filename) { 34 | if (errmsg) { 35 | SET_ERRMSG(errmsg, "Filename is null"); 36 | } 37 | return NULL; 38 | } 39 | 40 | ret = sqlite3_open(filename, &db); 41 | if (ret != SQLITE_OK) { 42 | /** 43 | * NB: should close db though we open this db failed, 44 | * or else a memory will leak 45 | */ 46 | sqlite3_close(db); 47 | char msg[128]; 48 | snprintf(msg, sizeof(msg), "Open file: %s failed, errcode is %d", 49 | filename, ret); 50 | SET_ERRMSG(errmsg, msg); 51 | return NULL; 52 | } 53 | 54 | return db; 55 | } 56 | 57 | /** 58 | * Close a sqlite3 database 59 | * 60 | * @param db 61 | * @param errmsg 62 | */ 63 | void sws_close_db(SwsDB *db, char **errmsg) 64 | { 65 | int ret; 66 | 67 | if (!db) { 68 | SET_ERRMSG(errmsg, "Filename is null"); 69 | return ; 70 | } 71 | 72 | ret = sqlite3_close(db); 73 | if (ret != SQLITE_OK) { 74 | char msg[128]; 75 | snprintf(msg, sizeof(msg), "Close DB failed: %s", sqlite3_errmsg(db)); 76 | SET_ERRMSG(errmsg, msg); 77 | return ; 78 | } 79 | } 80 | 81 | /** 82 | * Excute a sql sentence 83 | * 84 | * @param db 85 | * @param sql Sql sentence you want to excute 86 | * @param errmsg 87 | * 88 | * @return 0 if everything is ok, else return -1 89 | */ 90 | int sws_exec_sql(SwsDB *db, const char *sql, char **errmsg) 91 | { 92 | char *err = NULL; 93 | int ret = 0; 94 | 95 | if (!db || !sql) { 96 | SET_ERRMSG(errmsg, "Some parameterment is null"); 97 | return -1; 98 | } 99 | 100 | ret = sqlite3_exec(db, sql, NULL, NULL, &err); 101 | if (ret != SQLITE_OK) { 102 | char msg[512]; 103 | snprintf(msg, sizeof(msg), "\"%s\" failed: %s", sql, err); 104 | SET_ERRMSG(errmsg, msg); 105 | sqlite3_free(err); 106 | return -1; 107 | } 108 | 109 | return 0; 110 | } 111 | 112 | /** 113 | * Start a query 114 | * 115 | * @param db 116 | * @param sql 117 | * @param stmt 118 | * @param errmsg 119 | * 120 | * @return 0 if start successfully, else return -1 and stored error 121 | * information in errmsg if errmsg is not null. 122 | */ 123 | int sws_query_start(SwsDB *db, const char *sql, SwsStmt **stmt, char **errmsg) 124 | { 125 | int ret; 126 | 127 | if (!db || !sql || !stmt) { 128 | SET_ERRMSG(errmsg, "Some parameterment is null"); 129 | return -1; 130 | } 131 | 132 | ret = sqlite3_prepare_v2(db, sql, -1, (sqlite3_stmt **)stmt, 0); 133 | if (ret != SQLITE_OK) { 134 | char msg[512]; 135 | snprintf(msg, sizeof(msg), "\"%s\" failed: %s", 136 | sql, sqlite3_errmsg(db)); 137 | SET_ERRMSG(errmsg, msg); 138 | return -1; 139 | } 140 | 141 | return 0; 142 | } 143 | 144 | /** 145 | * Query next result 146 | * 147 | * @param stmt 148 | * @param errmsg 149 | * 150 | * @return 0 if query successfully, else return -1 and stored error 151 | * information in errmsg if errmsg is not null. 152 | */ 153 | int sws_query_next(SwsStmt *stmt, char **errmsg) 154 | { 155 | int ret; 156 | 157 | if (!stmt) { 158 | SET_ERRMSG(errmsg, "Some parameterment is null"); 159 | return -1; 160 | } 161 | 162 | ret = sqlite3_step(stmt); 163 | if (ret != SQLITE_ROW) { 164 | char msg[128]; 165 | snprintf(msg, sizeof(msg), "Query failed, errcode: %d", ret); 166 | SET_ERRMSG(errmsg, msg); 167 | return -1; 168 | } 169 | 170 | return 0; 171 | } 172 | 173 | /** 174 | * 175 | * 176 | * @param stmt 177 | * @param clm_index Column number 178 | * @param buf Store query result 179 | * @param buflen Max length of buffer which store query result in 180 | * @param errmsg 181 | * 182 | * @return 0 if query successfully, else return -1 and stored error 183 | * information in errmsg if errmsg is not null. 184 | */ 185 | int sws_query_column(SwsStmt *stmt, int clm_index, char *buf, int buflen, 186 | char **errmsg) 187 | { 188 | const unsigned char *result; 189 | 190 | if (!stmt || clm_index <0 || !buf || buflen <= 0) { 191 | SET_ERRMSG(errmsg, "Some parameterment is null"); 192 | return -1; 193 | } 194 | 195 | result = sqlite3_column_text(stmt, clm_index); 196 | if (!result) { 197 | char msg[64]; 198 | snprintf(msg, sizeof(msg), "Query %d column failed", clm_index); 199 | SET_ERRMSG(errmsg, msg); 200 | return -1; 201 | } 202 | 203 | snprintf(buf, buflen, "%s", result); 204 | return 0; 205 | } 206 | 207 | /** 208 | * 209 | * 210 | * @param stmt 211 | * @param errmsg 212 | * 213 | * @return 0 if end successfully, else return -1 and stored error 214 | * information in errmsg if errmsg is not null. 215 | */ 216 | int sws_query_end(SwsStmt *stmt, char **errmsg) 217 | { 218 | int ret; 219 | 220 | if (!stmt) { 221 | SET_ERRMSG(errmsg, "Some parameterment is null"); 222 | return -1; 223 | } 224 | 225 | ret = sqlite3_finalize(stmt); 226 | 227 | if (ret != SQLITE_OK) { 228 | char msg[64]; 229 | snprintf(msg, sizeof(msg), "End query failed, errcode: %d", ret); 230 | SET_ERRMSG(errmsg, msg); 231 | return -1; 232 | } 233 | 234 | return 0; 235 | } 236 | 237 | /** 238 | * Excute a SQL directly, dont need to open DB and close DB 239 | * 240 | * @param filename 241 | * @param sql 242 | * @param errmsg 243 | * 244 | * @return 0 if excute successfully, else return -1. 245 | */ 246 | int sws_exec_sql_directly(const char *filename, const char *sql, char **errmsg) 247 | { 248 | int ret; 249 | SwsDB *db = NULL; 250 | 251 | if (!filename || !sql) { 252 | SET_ERRMSG(errmsg, "Some parameterment is null"); 253 | goto failed; 254 | } 255 | 256 | db = sws_open_db(filename, errmsg); 257 | if (!db) { 258 | goto failed; 259 | } 260 | 261 | ret = sws_exec_sql(db, sql, errmsg); 262 | if (ret) { 263 | goto failed; 264 | } 265 | 266 | sws_close_db(db, NULL); 267 | 268 | return 0; 269 | 270 | failed: 271 | if (db) 272 | sws_close_db(db, NULL); 273 | return -1; 274 | } 275 | 276 | #if 0 277 | /* gcc -o test swsqlite.c -Wall -lsqlite3 */ 278 | #include 279 | int main(int argc, char *argv[]) 280 | { 281 | int ret; 282 | SwsStmt *stmt = NULL; 283 | 284 | /* Open DB */ 285 | SwsDB *db = sws_open_db("/tmp/test_sws.db", NULL); 286 | if (!db) { 287 | return -1; 288 | } 289 | 290 | /* Excute SQL */ 291 | ret = sws_exec_sql(db, "create table if not exists config(" 292 | "id integer primary key asc autoincrement," 293 | "family,key,value); " 294 | "INSERT into config (family, key, value) " 295 | "VALUES('sws', 'version', '0.0.1');" 296 | "INSERT into config (family, key, value) " 297 | "VALUES('sws', 'status', 'test');", NULL); 298 | if (ret) { 299 | goto failed; 300 | } 301 | 302 | /* Query */ 303 | ret = sws_query_start(db, "SELECT key,value FROM config;", &stmt, NULL); 304 | if (ret) { 305 | goto failed; 306 | } 307 | while (!sws_query_next(stmt, NULL)) { 308 | char key[128], value[128]; 309 | sws_query_column(stmt, 0, key, sizeof(key), NULL); 310 | sws_query_column(stmt, 1, value, sizeof(value), NULL); 311 | printf ("%s=%s\n", key, value); 312 | } 313 | sws_query_end(stmt, NULL); 314 | 315 | /* Close DB */ 316 | sws_close_db(db, NULL); 317 | 318 | /* Excute SQL directly */ 319 | sws_exec_sql_directly("/tmp/test_sws.db", "INSERT INTO configs " 320 | "(family,key,value) VALUES('1', '2', '3');", NULL); 321 | 322 | return 0; 323 | 324 | failed: 325 | sws_close_db(db, NULL); 326 | return -1; 327 | } 328 | #endif 329 | -------------------------------------------------------------------------------- /src/lwdb/swsqlite.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @file swsqlite.h 3 | * @author mathslinux 4 | * @date Wed May 30 10:37:01 2012 5 | * 6 | * @brief Simple wrapper of sqlite 7 | * 8 | * 9 | */ 10 | 11 | #ifndef SSQLITE_H 12 | #define SSQLITE_H 13 | 14 | typedef void SwsDB; 15 | typedef void SwsStmt; 16 | 17 | /** 18 | * Open a sqlite3 database 19 | * 20 | * @param filename DB filename 21 | * @param errmsg If open db failed, a error information will be stored in 22 | * errmsg if you pass this parameterment. 23 | * 24 | * @return A new SwsDB object, or NULL if something error happens 25 | */ 26 | SwsDB *sws_open_db(const char *filename, char **errmsg); 27 | 28 | /** 29 | * Close a sqlite3 database 30 | * 31 | * @param db 32 | * @param errmsg 33 | */ 34 | void sws_close_db(SwsDB *db, char **errmsg); 35 | 36 | /** 37 | * Excute a sql sentence 38 | * 39 | * @param db 40 | * @param sql Sql sentence you want to excute 41 | * @param errmsg 42 | * 43 | * @return 0 if everything is ok, else return -1 44 | */ 45 | int sws_exec_sql(SwsDB *db, const char *sql, char **errmsg); 46 | 47 | /************************************************************************/ 48 | /** 49 | * Below is query API. If you want to query something from sqlite3 database. 50 | * Yuo just only call these API like this: 51 | * // open db; 52 | * SwsStmt *stmt = NULL; 53 | * char *sql = "SELECT key,value FROM config;" 54 | * sws_query_start(db, sql, &stmt, NULL); 55 | * while (!sws_query_next(stmt)) { 56 | * char key[128], value[128]; 57 | * sws_query_column(stmt, 0, key, sizeof(key), NULL); 58 | * sws_query_column(stmt, 1, value, sizeof(value), NULL); 59 | * // Handle something 60 | * } 61 | * sws_query_end(stmt, NULL); 62 | * 63 | * Just so easy 64 | */ 65 | 66 | /** 67 | * Start a query 68 | * 69 | * @param db 70 | * @param sql 71 | * @param stmt 72 | * @param errmsg 73 | * 74 | * @return 0 if start successfully, else return -1 and stored error 75 | * information in errmsg if errmsg is not null. 76 | */ 77 | int sws_query_start(SwsDB *db, const char *sql, SwsStmt **stmt, char **errmsg); 78 | 79 | /** 80 | * Query next result 81 | * 82 | * @param stmt 83 | * @param errmsg 84 | * 85 | * @return 0 if query successfully, else return -1 and stored error 86 | * information in errmsg if errmsg is not null. 87 | */ 88 | int sws_query_next(SwsStmt *stmt, char **errmsg); 89 | 90 | /** 91 | * 92 | * 93 | * @param stmt 94 | * @param clm_index Column number 95 | * @param buf Store query result 96 | * @param buflen Max length of buffer which store query result in 97 | * @param errmsg 98 | * 99 | * @return 0 if query successfully, else return -1 and stored error 100 | * information in errmsg if errmsg is not null. 101 | */ 102 | int sws_query_column(SwsStmt *stmt, int clm_index, char *buf, int buflen, 103 | char **errmsg); 104 | /** 105 | * 106 | * 107 | * @param stmt 108 | * @param errmsg 109 | * 110 | * @return 0 if end successfully, else return -1 and stored error 111 | * information in errmsg if errmsg is not null. 112 | */ 113 | int sws_query_end(SwsStmt *stmt, char **errmsg); 114 | 115 | /** 116 | * Excute a SQL directly, dont need to open DB and close DB 117 | * 118 | * @param filename 119 | * @param sql 120 | * @param errmsg 121 | * 122 | * @return 0 if excute successfully, else return -1. 123 | */ 124 | int sws_exec_sql_directly(const char *filename, const char *sql, char **errmsg); 125 | 126 | #endif 127 | -------------------------------------------------------------------------------- /test/Makefile.am: -------------------------------------------------------------------------------- 1 | AM_CFLAGS=-I${srcdir}/../src/include/lwqq -I${srcdir}/../src/liblwqq/libghttp \ 2 | -I${srcdir}/../src/lwdb 3 | noinst_PROGRAMS=testlogin testlwdb testsendmsg 4 | 5 | testlogin_SOURCES=test_login.c 6 | testlogin_LDADD=../src/liblwqq/liblwqq.la \ 7 | ../src/liblwqq/libghttp/libghttp.la $(ZLIB_LIBS) \ 8 | $(LIBEV_LIBS) 9 | 10 | testsendmsg_SOURCES=test_sendmsg.c 11 | testsendmsg_LDADD=../src/liblwqq/liblwqq.la \ 12 | ../src/liblwqq/libghttp/libghttp.la $(ZLIB_LIBS) \ 13 | $(LIBEV_LIBS) 14 | 15 | testlwdb_SOURCES= test_lwdb.c 16 | testlwdb_LDADD=../src/liblwqq/liblwqq.la \ 17 | ../src/liblwqq/libghttp/libghttp.la $(ZLIB_LIBS) \ 18 | ../src/lwdb/liblwdb.la \ 19 | $(LIBEV_LIBS) 20 | -------------------------------------------------------------------------------- /test/test_lwdb.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file test_lwdb.c 3 | * @author mathslinux 4 | * @date Sat Jun 9 20:02:38 2012 5 | * 6 | * @brief Lwqq Database test module 7 | * 8 | * 9 | */ 10 | 11 | #include "login.h" 12 | #include "logger.h" 13 | #include "info.h" 14 | #include "smemory.h" 15 | #include "lwdb.h" 16 | 17 | int main(int argc, char *argv[]) 18 | { 19 | LwdbGlobalDB *gdb = NULL; 20 | LwdbUserDB *udb = NULL; 21 | LwdbGlobalUserEntry *e = NULL; 22 | LwqqBuddy *b1, b2 = { 23 | .qqnumber = "244569070", 24 | .uin = "4744839", 25 | .nick = "hello", 26 | .phone = "32344556", 27 | }; 28 | 29 | lwdb_init(); 30 | gdb = lwdb_globaldb_new(); 31 | if (!gdb) { 32 | lwqq_log(LOG_ERROR, "error\n"); 33 | goto done; 34 | } 35 | e = gdb->query_user_info(gdb, "3456345"); 36 | if (!e) { 37 | gdb->add_new_user(gdb, "3456345"); 38 | e = gdb->query_user_info(gdb, "3456345"); 39 | if (!e) { 40 | goto done; 41 | } 42 | } 43 | 44 | udb = lwdb_userdb_new("3456345"); 45 | if (!udb) { 46 | goto done; 47 | } 48 | lwqq_log(LOG_NOTICE, "%s,%s,%s,%s,%s\n", 49 | e->qqnumber, e->db_name, e->password, e->status, e->rempwd); 50 | 51 | b1 = udb->query_buddy_info(udb, "244569070"); 52 | if (b1) { 53 | lwqq_buddy_free(b1); 54 | } 55 | udb->update_buddy_info(udb, &b2); 56 | 57 | done: 58 | lwdb_globaldb_free_user_entry(e); 59 | lwdb_globaldb_free(gdb); 60 | lwdb_userdb_free(udb); 61 | lwdb_finalize(); 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /test/test_sendmsg.c: -------------------------------------------------------------------------------- 1 | /** 2 | * @file test_sendmsg.c 3 | * @author mathslinux 4 | * @date Sat Jun 9 20:06:56 2012 5 | * 6 | * @brief Lwqq login test module 7 | * 8 | * 9 | */ 10 | 11 | #include 12 | #include 13 | 14 | #include "login.h" 15 | #include "logger.h" 16 | #include "info.h" 17 | #include "smemory.h" 18 | #include "msg.h" 19 | 20 | static char *get_vc() 21 | { 22 | char buf[1024] = {0}; 23 | 24 | FILE *f = fopen("/tmp/test.txt", "r"); 25 | if (!f) 26 | return NULL; 27 | 28 | char *i = fgets(buf, sizeof(buf), f); 29 | if (!i) 30 | return NULL; 31 | fclose(f); 32 | int len = strlen(buf); 33 | buf[len - 1] = '\0'; 34 | printf ("%s\n", i); 35 | return s_strdup(buf); 36 | } 37 | 38 | static void test_sendmsg(const char *qqnumber, const char *password) 39 | { 40 | LwqqClient *lc = lwqq_client_new(qqnumber, password); 41 | if (!lc) 42 | return ; 43 | 44 | LwqqErrorCode err; 45 | lwqq_login(lc, &err); 46 | if (err == LWQQ_EC_LOGIN_NEED_VC) { 47 | unlink("/tmp/test.txt"); 48 | while (1) { 49 | if (!access("/tmp/test.txt", F_OK)) { 50 | sleep(1); 51 | break; 52 | } 53 | sleep(1); 54 | } 55 | lc->vc->str = get_vc(); 56 | printf ("get vc: %s\n", lc->vc->str); 57 | 58 | lwqq_login(lc, &err); 59 | } else if (err != LWQQ_EC_OK) { 60 | lwqq_log(LOG_ERROR, "Login error, exit\n"); 61 | goto done; 62 | } 63 | lwqq_log(LOG_NOTICE, "Login successfully\n"); 64 | 65 | lwqq_info_get_friends_info(lc, &err); 66 | if (err == LWQQ_EC_OK) { 67 | LwqqBuddy *buddy; 68 | LIST_FOREACH(buddy, &lc->friends, entries) { 69 | #if 0 70 | LwqqSendMsg *msg; 71 | if (!strcmp(buddy->nick, "mathslinux")) { 72 | msg = lwqq_sendmsg_new(lc, buddy->uin, "message", "Who are you?"); 73 | msg->send(msg); 74 | } 75 | #endif 76 | } 77 | 78 | } 79 | 80 | /* Logout test */ 81 | sleep(3); 82 | lwqq_logout(lc, &err); 83 | if (err != LWQQ_EC_OK) { 84 | lwqq_log(LOG_DEBUG, "Logout failed\n"); 85 | } else { 86 | lwqq_log(LOG_DEBUG, "Logout sucessfully\n"); 87 | } 88 | 89 | done: 90 | lwqq_client_free(lc); 91 | } 92 | 93 | int main(int argc, char *argv[]) 94 | { 95 | if (argc != 3) { 96 | return -1; 97 | } 98 | test_sendmsg(argv[1], argv[2]); 99 | return 0; 100 | } 101 | 102 | --------------------------------------------------------------------------------