summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpescuma <pescuma@c086bb3d-8645-0410-b8da-73a8550f86e7>2008-02-20 04:23:23 +0000
committerpescuma <pescuma@c086bb3d-8645-0410-b8da-73a8550f86e7>2008-02-20 04:23:23 +0000
commit965f0ca12bc0c090f9d25a856c36645935832072 (patch)
tree87ec2f3d7e4f74e6e0f3d36fba94d9a7d2ab3057
Initial import of Emoticons plugin (version 0.0.1.0)
git-svn-id: http://pescuma.googlecode.com/svn/trunk/Miranda@21 c086bb3d-8645-0410-b8da-73a8550f86e7
-rw-r--r--Plugins/emoticons/Docs/emoticons_changelog.txt46
-rw-r--r--Plugins/emoticons/Docs/emoticons_readme.txt52
-rw-r--r--Plugins/emoticons/Docs/emoticons_version.txt1
-rw-r--r--Plugins/emoticons/Docs/langpack_emoticons.txt17
-rw-r--r--Plugins/emoticons/OleImage.cpp923
-rw-r--r--Plugins/emoticons/OleImage.h150
-rw-r--r--Plugins/emoticons/commons.h218
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/Tango.mep2
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/act-up.pngbin0 -> 1317 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/airplane.pngbin0 -> 940 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/alien.pngbin0 -> 1452 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/angel.pngbin0 -> 1587 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/angry.pngbin0 -> 1354 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/arrogant.pngbin0 -> 1307 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/bashful.pngbin0 -> 1281 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/beat-up.pngbin0 -> 1317 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/beauty.pngbin0 -> 1363 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/beer.pngbin0 -> 1382 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/blowkiss.pngbin0 -> 1283 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/bomb.pngbin0 -> 1110 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/boring.pngbin0 -> 1384 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/bowl.pngbin0 -> 1157 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/brb.pngbin0 -> 873 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/bug.pngbin0 -> 1451 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/bye.pngbin0 -> 1316 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/cake.pngbin0 -> 1114 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/call-me.pngbin0 -> 1374 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/camera.pngbin0 -> 974 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/can.pngbin0 -> 1028 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/car.pngbin0 -> 1481 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/cat.pngbin0 -> 1269 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/chicken.pngbin0 -> 1293 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/cigarette.pngbin0 -> 1146 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/clap.pngbin0 -> 1334 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/clock.pngbin0 -> 1352 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/cloudy.pngbin0 -> 1119 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/clover.pngbin0 -> 1266 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/clown.pngbin0 -> 1467 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/coffee.pngbin0 -> 1326 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/coins.pngbin0 -> 1330 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/computer.pngbin0 -> 891 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/confused.pngbin0 -> 1280 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/console.pngbin0 -> 1001 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/cow.pngbin0 -> 1146 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/cowboy.pngbin0 -> 1490 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/crying.pngbin0 -> 1319 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/curl-lip.pngbin0 -> 1269 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/curse.pngbin0 -> 1342 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/cute.pngbin0 -> 1275 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/dance.pngbin0 -> 1359 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/dazed.pngbin0 -> 1275 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/desire.pngbin0 -> 1291 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/devilish.pngbin0 -> 1457 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/disapointed.pngbin0 -> 1225 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/disdain.pngbin0 -> 1288 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/doctor.pngbin0 -> 1301 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/dog.pngbin0 -> 1497 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/doh.pngbin0 -> 1284 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/dont-know.pngbin0 -> 1265 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/drink.pngbin0 -> 1125 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/drool.pngbin0 -> 1301 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/eat.pngbin0 -> 1335 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/embarrassed.pngbin0 -> 1284 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/excruciating.pngbin0 -> 1242 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/eyeroll.pngbin0 -> 1239 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/female.pngbin0 -> 990 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/film.pngbin0 -> 1365 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/fingers-crossed.pngbin0 -> 1373 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/foot-in-mouth.pngbin0 -> 1274 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/freaked-out.pngbin0 -> 1236 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/ghost.pngbin0 -> 1277 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/giggle.pngbin0 -> 1305 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/glass-cool.pngbin0 -> 1302 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/glass-nerdy.pngbin0 -> 1519 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/go-away.pngbin0 -> 1324 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/goat.pngbin0 -> 1336 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/hammer.pngbin0 -> 1004 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/handcuffs.pngbin0 -> 1393 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/handshake.pngbin0 -> 1390 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/highfive.pngbin0 -> 1499 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/hug-left.pngbin0 -> 1344 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/hug-right.pngbin0 -> 1354 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/hungry.pngbin0 -> 1341 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/hypnotized.pngbin0 -> 1315 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/in-love.pngbin0 -> 1366 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/island.pngbin0 -> 1122 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/jump.pngbin0 -> 1316 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/kiss.pngbin0 -> 1345 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/kissed.pngbin0 -> 1345 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/knife.pngbin0 -> 1093 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/lamp.pngbin0 -> 1259 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/lashes.pngbin0 -> 1341 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/laugh.pngbin0 -> 1250 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/liquor.pngbin0 -> 762 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/loser.pngbin0 -> 1387 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/love-over.pngbin0 -> 1342 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/love.pngbin0 -> 1069 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/lying.pngbin0 -> 1274 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/mad-tongue.pngbin0 -> 1303 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/mail.pngbin0 -> 881 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/male.pngbin0 -> 1177 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/mean.pngbin0 -> 1277 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/meeting.pngbin0 -> 1438 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/mobile.pngbin0 -> 690 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/moneymouth.pngbin0 -> 1324 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/monkey.pngbin0 -> 1347 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/moon.pngbin0 -> 1180 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/msn.pngbin0 -> 1281 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/music.pngbin0 -> 941 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/nailbiting.pngbin0 -> 1286 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/neutral.pngbin0 -> 1245 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/no.pngbin0 -> 1054 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/on-the-phone.pngbin0 -> 1393 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/party.pngbin0 -> 1488 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/peace.pngbin0 -> 1426 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/phone.pngbin0 -> 1067 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/pick-fight.pngbin0 -> 1334 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/pig.pngbin0 -> 1383 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/pill.pngbin0 -> 1085 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/pissed-off.pngbin0 -> 1342 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/pizza.pngbin0 -> 943 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/plate.pngbin0 -> 1291 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/poop.pngbin0 -> 998 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/pray.pngbin0 -> 1392 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/present.pngbin0 -> 975 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/pumpkin.pngbin0 -> 1398 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/qq.pngbin0 -> 1436 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/question.pngbin0 -> 1491 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/quiet.pngbin0 -> 1248 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/rain.pngbin0 -> 765 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/rainbow.pngbin0 -> 767 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/rock.pngbin0 -> 1359 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/rose-dead.pngbin0 -> 1289 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/rose.pngbin0 -> 1062 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/rotfl.pngbin0 -> 1318 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/sad.pngbin0 -> 1283 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/sarcastic.pngbin0 -> 1274 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/scream.pngbin0 -> 1242 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/search.pngbin0 -> 1060 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/secret.pngbin0 -> 1304 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/shame.pngbin0 -> 1290 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/sheep.pngbin0 -> 1123 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/shock.pngbin0 -> 1264 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/shout.pngbin0 -> 1288 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/shut-mouth.pngbin0 -> 1306 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/sick.pngbin0 -> 1309 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/silly.pngbin0 -> 1266 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/skeleton.pngbin0 -> 1299 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/skywalker.pngbin0 -> 1554 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/sleepy.pngbin0 -> 1400 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/smile-big.pngbin0 -> 1257 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/smile.pngbin0 -> 1271 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/smirk.pngbin0 -> 1256 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/snail.pngbin0 -> 1200 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/snicker.pngbin0 -> 1274 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/snowman.pngbin0 -> 1323 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/soccerball.pngbin0 -> 1351 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/soldier.pngbin0 -> 1402 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/star.pngbin0 -> 976 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/starving.pngbin0 -> 1341 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/stop.pngbin0 -> 1324 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/struggle.pngbin0 -> 1269 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/sun.pngbin0 -> 1243 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/sweat.pngbin0 -> 1275 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/talktohand.pngbin0 -> 1349 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/teeth.pngbin0 -> 1268 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/terror.pngbin0 -> 1259 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/thinking.pngbin0 -> 1282 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/thunder.pngbin0 -> 977 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/time-out.pngbin0 -> 1268 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/tongue.pngbin0 -> 1260 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/tremble.pngbin0 -> 1298 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/turtle.pngbin0 -> 1078 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/tv.pngbin0 -> 632 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/umbrella.pngbin0 -> 1095 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/usa.pngbin0 -> 540 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/vampire.pngbin0 -> 1315 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/victory.pngbin0 -> 1387 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/waiting.pngbin0 -> 1251 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/watermelon.pngbin0 -> 1189 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/weep.pngbin0 -> 1267 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/wilt.pngbin0 -> 1260 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/wink.pngbin0 -> 1276 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/worship.pngbin0 -> 1262 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/yawn.pngbin0 -> 1286 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/yes.pngbin0 -> 1011 bytes
-rw-r--r--Plugins/emoticons/data/Customize/Emoticons/Tango/yin-yang.pngbin0 -> 1262 bytes
-rw-r--r--Plugins/emoticons/data/Plugins/Emoticons/Default.emo16
-rw-r--r--Plugins/emoticons/data/Plugins/Emoticons/ICQ.emo30
-rw-r--r--Plugins/emoticons/data/Plugins/Emoticons/JGMAIL.emo19
-rw-r--r--Plugins/emoticons/data/Plugins/Emoticons/MSN.emo83
-rw-r--r--Plugins/emoticons/data/Plugins/Emoticons/YAHOO.emo89
-rw-r--r--Plugins/emoticons/data/Plugins/Emoticons/downloading.gifbin0 -> 1849 bytes
-rw-r--r--Plugins/emoticons/emoticons.cpp2172
-rw-r--r--Plugins/emoticons/emoticons.dsp259
-rw-r--r--Plugins/emoticons/emoticons.dsw29
-rw-r--r--Plugins/emoticons/emoticons.sln26
-rw-r--r--Plugins/emoticons/emoticons.vcproj775
-rw-r--r--Plugins/emoticons/m_emoticons.h27
-rw-r--r--Plugins/emoticons/options.cpp376
-rw-r--r--Plugins/emoticons/options.h51
-rw-r--r--Plugins/emoticons/resource.h29
-rw-r--r--Plugins/emoticons/resource.rc155
-rw-r--r--Plugins/emoticons/sdk/anismiley.tlh78
-rw-r--r--Plugins/emoticons/sdk/m_anismiley.h116
-rw-r--r--Plugins/emoticons/sdk/m_customsmileys.h52
-rw-r--r--Plugins/emoticons/sdk/m_folders.h205
-rw-r--r--Plugins/emoticons/sdk/m_metacontacts.h162
-rw-r--r--Plugins/emoticons/sdk/m_smileyadd.h182
-rw-r--r--Plugins/emoticons/sdk/m_updater.h146
-rw-r--r--Plugins/emoticons/sdk/m_variables.h720
-rw-r--r--Plugins/emoticons/selwin.cpp706
-rw-r--r--Plugins/emoticons/selwin.h29
-rw-r--r--Plugins/utils/ContactAsyncQueue.cpp222
-rw-r--r--Plugins/utils/ContactAsyncQueue.h93
-rw-r--r--Plugins/utils/mir_buffer.h452
-rw-r--r--Plugins/utils/mir_icons.cpp49
-rw-r--r--Plugins/utils/mir_icons.h33
-rw-r--r--Plugins/utils/mir_log.cpp133
-rw-r--r--Plugins/utils/mir_log.h41
-rw-r--r--Plugins/utils/mir_memory.cpp70
-rw-r--r--Plugins/utils/mir_memory.h68
-rw-r--r--Plugins/utils/mir_options.cpp541
-rw-r--r--Plugins/utils/mir_options.h68
224 files changed, 9711 insertions, 0 deletions
diff --git a/Plugins/emoticons/Docs/emoticons_changelog.txt b/Plugins/emoticons/Docs/emoticons_changelog.txt
new file mode 100644
index 0000000..8971a58
--- /dev/null
+++ b/Plugins/emoticons/Docs/emoticons_changelog.txt
@@ -0,0 +1,46 @@
+Emoticons
+
+Changelog:
+
+. 0.0.1.0
+ + Allows loading emoticons from folder with proto name
+ + Allows to write generic paths (inside pack folder) for an emoticon in .mep
+ + Random emoticons in options page
+
+. 0.0.0.9
+ + Use AniSmiley if avaiable (recomended) or my control as fallback (more buggy)
+ * Updated AniSmiley to latest version (a lot of fixes)
+ * Fixes and other stuff
+
+. 0.0.0.8
+ + Created my own ole image control
+
+. 0.0.0.7
+ + Option to only replace emoticons surrounded by spaces
+
+. 0.0.0.6
+ * Fix for URLs in history
+ * Fix for HOME key in input area
+
+. 0.0.0.5
+ + Added Yahoo emoticons
+ * Fix for emoticons like :(|) in input area
+
+. 0.0.0.4
+ * Fix for emoticons in history
+ + New emoticon pack selection control
+
+. 0.0.0.3
+ * Protocol and pack names are case insensitive
+ + Tooltips in selection window
+ + Show smileys without images as text in selection window
+ + Added default module
+ * Fix for transparent images
+
+. 0.0.0.2
+ * Fix if not using metacontacts
+ * Fix for first message only with :)
+ + Added jgmail emoticons (still missing one)
+
+. 0.0.0.1
+ + Initial version \ No newline at end of file
diff --git a/Plugins/emoticons/Docs/emoticons_readme.txt b/Plugins/emoticons/Docs/emoticons_readme.txt
new file mode 100644
index 0000000..4b41753
--- /dev/null
+++ b/Plugins/emoticons/Docs/emoticons_readme.txt
@@ -0,0 +1,52 @@
+Emoticons plugin
+----------------
+
+CAUTION: THIS IS AN ALPHA STAGE PLUGIN. IT CAN DO VERY BAD THINGS. USE AT YOUR OWN RISK.
+
+This is a plugin to replace emoticons in message windows. It support replacement in the log and in message entry area. Animated gifs are supported in both areas. For that AniSmiley plugin is supported and advised.
+
+It is based in two concepts:
+
+1. The emoticons configuration is per protocol, and comes bundled with the plugin. They reference emoticons by a set of pre-configured names (they can't create new names - if someone needs new names, please tell me) and set the shortcut and names for the emoticons the protocol support.
+They are *.emo files and must be inside <Miranda>\Plugins\Emoticons
+Currently I created a pack for MSN, ICQ, JGMAIL, YAHOO and a Default. If someone knows where I can find a list of default emoticons for other protocols, please tell me.
+The format of the emo file, it is like this:
+ "smile" = "Small smile", "/wx" "/:)" "/small_smile"
+field 1 -> "smile" -> The unique name of the emoticon (as the Tango pack has it)
+field 2 -> "Small smile" -> A text description for the emoticon, as the protocol uses it. This should be in english (so all users can 'understand' it), and is translatable via language pack
+field 3 -> "/wx" -> Default emoticon text (used when using the selection window)
+fields 4 ... -> "/:)" "/small_smile" -> Other possible texts. Please, try get all possible texts. Also, note that this is case sensitive, so if the protocol is not you have to type all possible combinations.
+
+2. Emoticon packs, containing the emoticons to show, only contain the images and a .mep file describing the creator.
+Each one must be a folder inside Customize\Emoticons, with the images beeing the pre-configured name of the smiley.
+If you want to change images for a protocol, you can create a sub-folder with the protocol name and put the images there (with the images beeing the pre-configured name of the smiley). Currently gif (included animated ones), png and jpeg images are supported.
+The name of the pack is the name of the folder, and a file <Pack name>.mep can exist inside the folder, containing this entries (all of then are optional):
+Name: <Full name of the pack>
+Creator: <Artist name>
+Updater URL: <URL for updating this pack - not yet implemented>
+
+Also, the mep file can expecify the filename for an emoticon, in a line like:
+"<The unique name of the emoticon>" = "<Relative path from pack foler>"
+For example:
+"smile" = "01.gif"
+This will affect all protocols. If you want to change the image for a protocol only, you can write:
+"ICQ\smile" = "ICQ_smile01.gif"
+or
+"ICQ\smile" = "ICQ\smile01.gif"
+
+
+A default pack, containing Tango Emoticons (made by Hylke) is packed and can be used as an example.
+
+Currently there is a lot more work to be done on this plugin, but I wanted to show an initial version, so I could get some feedback.
+
+Thanks to FYR for the AniSmiley plugin and to Hylke for the nice emoticons.
+
+To report bugs/make suggestions, go to the forum thread: http://forums.miranda-im.org/showthread.php?t=17210
+
+
+TODO:
+- Per protocol pack
+- Support for custom smileys
+- Updater support for Emoticon Packs
+- Support h++ (works using AniSmiley)
+
diff --git a/Plugins/emoticons/Docs/emoticons_version.txt b/Plugins/emoticons/Docs/emoticons_version.txt
new file mode 100644
index 0000000..cb1a481
--- /dev/null
+++ b/Plugins/emoticons/Docs/emoticons_version.txt
@@ -0,0 +1 @@
+Emoticons 0.0.1.0 \ No newline at end of file
diff --git a/Plugins/emoticons/Docs/langpack_emoticons.txt b/Plugins/emoticons/Docs/langpack_emoticons.txt
new file mode 100644
index 0000000..9bc5afe
--- /dev/null
+++ b/Plugins/emoticons/Docs/langpack_emoticons.txt
@@ -0,0 +1,17 @@
+; Emoticons
+; Author: Pescuma
+
+; Options
+
+[Message Sessions]
+[Emoticons]
+
+[ Emoticons ]
+[by %s]
+[Replace emoticons in text input area too]
+[Use default emoticon pack for unknown protocols]
+[Only replace emoticons surrounded by spaces]
+[Download more emoticon packs]
+
+[Protocols Configuration]
+[Emoticon Packs] \ No newline at end of file
diff --git a/Plugins/emoticons/OleImage.cpp b/Plugins/emoticons/OleImage.cpp
new file mode 100644
index 0000000..cdadcee
--- /dev/null
+++ b/Plugins/emoticons/OleImage.cpp
@@ -0,0 +1,923 @@
+#include "commons.h"
+
+#define GIF_DISPOSAL_UNSPECIFIED 0
+#define GIF_DISPOSAL_LEAVE 1
+#define GIF_DISPOSAL_BACKGROUND 2
+#define GIF_DISPOSAL_PREVIOUS 3
+
+
+void PreMultiply(HBITMAP hBitmap);
+
+typedef map<UINT_PTR, OleImage *> ImageTimerMapType;
+
+static ImageTimerMapType timers;
+
+
+
+OleImage::OleImage(const char *aFilename, const TCHAR *aText, const TCHAR *aTooltip)
+{
+ memset(&si, 0, sizeof(si));
+ memset(&ag, 0, sizeof(ag));
+
+ refCount = 1;
+ filename = mir_strdup(aFilename);
+ originalFilename = mir_strdup(aFilename);
+ text = mir_tstrdup(aText);
+ closed = FALSE;
+
+ if (aTooltip == NULL)
+ tooltip = NULL;
+ else
+ {
+#ifdef UNICODE
+ tooltip = SysAllocString(aTooltip);
+#else
+ WCHAR *wtext = mir_t2u(aTooltip);
+ tooltip = SysAllocString(wtext);
+ mir_free(wtext);
+#endif
+ }
+
+ clientSite = NULL;
+ oleAdviseHolder = NULL;
+ viewAdviseSink = NULL;
+
+ if (!LoadImages())
+ return;
+
+ CalcSize();
+}
+
+
+OleImage::~OleImage()
+{
+ KillTimer();
+
+ if (clientSite != NULL)
+ {
+ clientSite->Release();
+ clientSite = NULL;
+ }
+
+ if (oleAdviseHolder != NULL)
+ {
+ oleAdviseHolder->Release();
+ oleAdviseHolder = NULL;
+ }
+
+ if (viewAdviseSink != NULL)
+ {
+ viewAdviseSink->Release();
+ viewAdviseSink = NULL;
+ }
+
+ DestroyImages();
+
+ if (tooltip != NULL)
+ {
+ SysFreeString(tooltip);
+ tooltip = NULL;
+ }
+ mir_free(filename);
+ mir_free(originalFilename);
+ mir_free(text);
+}
+
+
+BOOL OleImage::ShowDownloadingIcon(BOOL show)
+{
+ DestroyImages();
+
+ if (show)
+ {
+ mir_free(filename);
+
+ size_t len = lstrlen(protocolsFolder) + 20;
+ filename = (char *) mir_alloc(len * sizeof(char));
+ mir_snprintf(filename, len, TCHAR_STR_PARAM "\\downloading.gif", protocolsFolder);
+ }
+ else
+ {
+ mir_free(filename);
+
+ filename = mir_strdup(originalFilename);
+ }
+
+ if (!LoadImages())
+ return FALSE;
+
+ CalcSize();
+
+ OnImageChange();
+
+ return TRUE;
+}
+
+
+BOOL OleImage::LoadImages()
+{
+ animated = LoadAnimatedGif();
+ if (!animated)
+ if (!LoadStaticImage())
+ return FALSE;
+
+ return TRUE;
+}
+
+
+void OleImage::DestroyImages()
+{
+ if (animated)
+ {
+ DestroyAnimatedGif();
+ }
+ else if (si.hBmp != NULL)
+ {
+ DeleteObject(si.hBmp);
+ si.hBmp = NULL;
+ }
+
+ memset(&si, 0, sizeof(si));
+ memset(&ag, 0, sizeof(ag));
+}
+
+
+const char * OleImage::GetFilename() const
+{
+ return originalFilename;
+}
+
+
+const TCHAR * OleImage::GetText() const
+{
+ return text;
+}
+
+
+BOOL OleImage::isValid() const
+{
+ return animated || si.hBmp != NULL;
+}
+
+
+void OleImage::CalcSize()
+{
+ HDC hdc = GetDC(NULL);
+ int ppiX = GetDeviceCaps(hdc, LOGPIXELSX);
+ int ppiY = GetDeviceCaps(hdc, LOGPIXELSY);
+ ReleaseDC(NULL, hdc);
+
+ sizel.cx = (2540 * (width + 1) + ppiX / 2) / ppiX;
+ sizel.cy = (2540 * (height + 1) + ppiY / 2) / ppiY;
+}
+
+
+// IUnknown ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+HRESULT STDMETHODCALLTYPE OleImage::QueryInterface(/* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject)
+{
+ if (ppvObject == NULL)
+ return E_POINTER;
+
+ if (riid == IID_IOleImage)
+ {
+ *ppvObject = (OleImage *) this;
+ }
+ else if (riid == IID_IViewObject)
+ {
+ *ppvObject = (IViewObject *) this;
+ }
+ else if (riid == IID_IOleObject)
+ {
+ *ppvObject = (IOleObject *) this;
+ }
+ else if (riid == __uuidof(ITooltipData))
+ {
+ *ppvObject = (ITooltipData *) this;
+ }
+ else if (riid == IID_IUnknown)
+ {
+ *ppvObject = (OleImage *) this;
+ }
+ else
+ {
+ *ppvObject = NULL;
+ return E_NOINTERFACE;
+ }
+
+ AddRef();
+ return S_OK;
+}
+
+
+ULONG STDMETHODCALLTYPE OleImage::AddRef(void)
+{
+ return InterlockedIncrement(&refCount);
+}
+
+
+ULONG STDMETHODCALLTYPE OleImage::Release(void)
+{
+ LONG ret = InterlockedDecrement(&refCount);
+ if (ret <= 0)
+ delete this;
+ return ret;
+}
+
+
+
+// IOleObject //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+HRESULT STDMETHODCALLTYPE OleImage::SetClientSite(/* [unique][in] */ IOleClientSite *pClientSite)
+{
+ if (clientSite != NULL)
+ clientSite->Release();
+
+ clientSite = pClientSite;
+
+ if (clientSite != NULL)
+ clientSite->AddRef();
+
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::GetClientSite(/* [out] */ IOleClientSite **ppClientSite)
+{
+ *ppClientSite = clientSite;
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::SetHostNames(/* [in] */ LPCOLESTR szContainerApp, /* [unique][in] */ LPCOLESTR szContainerObj)
+{
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::Close(/* [in] */ DWORD dwSaveOption)
+{
+ KillTimer();
+
+ if (animated)
+ ag.started = FALSE;
+
+ closed = TRUE;
+
+// if (viewAdviseSink != NULL)
+// {
+// viewAdviseSink->OnClose();
+// //viewAdviseSink = NULL;
+// }
+
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::SetMoniker(/* [in] */ DWORD dwWhichMoniker, /* [unique][in] */ IMoniker *pmk)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::GetMoniker(/* [in] */ DWORD dwAssign, /* [in] */ DWORD dwWhichMoniker, /* [out] */ IMoniker **ppmk)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::InitFromData(/* [unique][in] */ IDataObject *pDataObject, /* [in] */ BOOL fCreation, /* [in] */ DWORD dwReserved)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::GetClipboardData(/* [in] */ DWORD dwReserved, /* [out] */ IDataObject **ppDataObject)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::DoVerb(/* [in] */ LONG iVerb, /* [unique][in] */ LPMSG lpmsg, /* [unique][in] */ IOleClientSite *pActiveSite, /* [in] */ LONG lindex, /* [in] */ HWND hwndParent, /* [unique][in] */ LPCRECT lprcPosRect)
+{
+ return OLEOBJ_E_NOVERBS;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::EnumVerbs(/* [out] */ IEnumOLEVERB **ppEnumOleVerb)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::Update(void)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::IsUpToDate(void)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::GetUserClassID(/* [out] */ CLSID *pClsid)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::GetUserType(/* [in] */ DWORD dwFormOfType, /* [out] */ LPOLESTR *pszUserType)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::SetExtent(/* [in] */ DWORD dwDrawAspect, /* [in] */ SIZEL *psizel)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::GetExtent(/* [in] */ DWORD dwDrawAspect, /* [out] */ SIZEL *psizel)
+{
+ if (dwDrawAspect != DVASPECT_CONTENT)
+ return DV_E_DVASPECT;
+ if (psizel == NULL)
+ return E_POINTER;
+
+ *psizel = sizel;
+
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::Advise(/* [unique][in] */ IAdviseSink *pAdvSink, /* [out] */ DWORD *pdwConnection)
+{
+ HRESULT hr = S_OK;
+ if (oleAdviseHolder == NULL)
+ hr = CreateOleAdviseHolder(&oleAdviseHolder);
+ if (SUCCEEDED(hr))
+ hr = oleAdviseHolder->Advise(pAdvSink, pdwConnection);
+ return hr;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::Unadvise(/* [in] */ DWORD dwConnection)
+{
+ if (oleAdviseHolder != NULL)
+ return oleAdviseHolder->Unadvise(dwConnection);
+ else
+ return E_FAIL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::EnumAdvise(/* [out] */ IEnumSTATDATA **ppenumAdvise)
+{
+ if (ppenumAdvise == NULL)
+ return E_POINTER;
+ *ppenumAdvise = NULL;
+
+ if (oleAdviseHolder != NULL)
+ return oleAdviseHolder->EnumAdvise(ppenumAdvise);
+ else
+ return E_FAIL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::GetMiscStatus(/* [in] */ DWORD dwAspect, /* [out] */ DWORD *pdwStatus)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::SetColorScheme(/* [in] */ LOGPALETTE *pLogpal)
+{
+ return E_NOTIMPL;
+}
+
+
+
+// IViewObject /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+HRESULT STDMETHODCALLTYPE OleImage::Draw(/* [in] */ DWORD dwDrawAspect, /* [in] */ LONG lindex, /* [unique][in] */ void *pvAspect, /* [unique][in] */ DVTARGETDEVICE *ptd, /* [in] */ HDC hdcTargetDev, /* [in] */ HDC hdcDraw, /* [in] */ LPCRECTL lprcBounds, /* [unique][in] */ LPCRECTL lprcWBounds, /* [in] */ BOOL ( STDMETHODCALLTYPE *pfnContinue )(ULONG_PTR dwContinue), /* [in] */ ULONG_PTR dwContinue)
+{
+ if (dwDrawAspect != DVASPECT_CONTENT)
+ return DV_E_DVASPECT;
+ if (hdcDraw == NULL)
+ return E_INVALIDARG;
+ if (lprcBounds == NULL)
+ return E_INVALIDARG;
+
+ if (closed)
+ closed = FALSE;
+
+ int oldBkMode = SetBkMode(hdcDraw, TRANSPARENT);
+
+ int w = min(lprcBounds->right - lprcBounds->left, width);
+ int h = min(lprcBounds->bottom - lprcBounds->top, height);
+
+ if (animated)
+ {
+ if (!ag.started)
+ AnimatedGifMountFrame();
+
+ HDC hdcImg = CreateCompatibleDC(hdcDraw);
+ HBITMAP oldBmp = (HBITMAP) SelectObject(hdcImg, ag.hbms[ag.frame.num]);
+
+ BLENDFUNCTION bf = {0};
+ bf.SourceConstantAlpha = 255;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ AlphaBlend(hdcDraw, lprcBounds->left, lprcBounds->top, w, h, hdcImg, 0, 0, w, h, bf);
+
+ SelectObject(hdcImg, oldBmp);
+ DeleteDC(hdcImg);
+
+ if (!ag.started)
+ {
+ SetTimer(ag.times[ag.frame.num]);
+ ag.started = TRUE;
+ }
+ }
+ else if (si.hBmp != NULL)
+ {
+ HDC hdcImg = CreateCompatibleDC(hdcDraw);
+ HBITMAP oldBmp = (HBITMAP) SelectObject(hdcImg, si.hBmp);
+
+ if (si.transparent)
+ {
+ BLENDFUNCTION bf = {0};
+ bf.SourceConstantAlpha = 255;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ AlphaBlend(hdcDraw, lprcBounds->left, lprcBounds->top, w, h, hdcImg, 0, 0, w, h, bf);
+ }
+ else
+ {
+ BitBlt(hdcDraw, lprcBounds->left, lprcBounds->top, w, h, hdcImg, 0, 0, SRCCOPY);
+ }
+
+ SelectObject(hdcImg, oldBmp);
+ DeleteDC(hdcImg);
+ }
+
+ SetBkMode(hdcDraw, oldBkMode);
+
+ return S_OK;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::GetColorSet(/* [in] */ DWORD dwDrawAspect, /* [in] */ LONG lindex, /* [unique][in] */ void *pvAspect, /* [unique][in] */ DVTARGETDEVICE *ptd, /* [in] */ HDC hicTargetDev, /* [out] */ LOGPALETTE **ppColorSet)
+{
+ return S_FALSE;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::Freeze(/* [in] */ DWORD dwDrawAspect, /* [in] */ LONG lindex, /* [unique][in] */ void *pvAspect, /* [out] */ DWORD *pdwFreeze)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::Unfreeze(/* [in] */ DWORD dwFreeze)
+{
+ return E_NOTIMPL;
+}
+
+
+HRESULT STDMETHODCALLTYPE OleImage::SetAdvise(/* [in] */ DWORD aspects, /* [in] */ DWORD advf, /* [unique][in] */ IAdviseSink *pAdvSink)
+{
+ if (aspects != DVASPECT_CONTENT)
+ return DV_E_DVASPECT;
+
+ if (viewAdviseSink != NULL)
+ viewAdviseSink->Release();
+
+ viewAdviseSink = pAdvSink;
+ viewAdvf = advf;
+
+ if (viewAdviseSink != NULL)
+ viewAdviseSink->AddRef();
+
+ if (viewAdviseSink != NULL && viewAdvf & ADVF_PRIMEFIRST)
+ SendOnViewChage();
+
+ return S_OK;
+}
+
+
+/* [local] */ HRESULT STDMETHODCALLTYPE OleImage::GetAdvise(/* [unique][out] */ DWORD *pAspects, /* [unique][out] */ DWORD *pAdvf, /* [out] */ IAdviseSink **ppAdvSink)
+{
+ *pAspects = DVASPECT_CONTENT;
+ *pAdvf = viewAdvf;
+ *ppAdvSink = viewAdviseSink;
+
+ return S_OK;
+}
+
+
+
+// ITooltipData /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+HRESULT OleImage::SetTooltip(/* [in] */ BSTR aTooltip)
+{
+ if (tooltip != NULL)
+ {
+ SysFreeString(tooltip);
+ tooltip = NULL;
+ }
+ if (aTooltip != NULL)
+ tooltip = SysAllocString(aTooltip);
+
+ return S_OK;
+}
+
+
+HRESULT OleImage::GetTooltip(/* [out, retval] */ BSTR * aTooltip)
+{
+ if (tooltip == NULL)
+ *aTooltip = NULL;
+ else
+ *aTooltip = SysAllocString(tooltip);
+
+ return S_OK;
+}
+
+
+
+
+void OleImage::OnImageChange()
+{
+ if (closed)
+ return;
+
+ SendOnViewChage();
+ NotifyHpp();
+}
+
+
+void OleImage::NotifyHpp()
+{
+ if (clientSite == NULL)
+ return;
+
+ IOleWindow *oleWindow = NULL;
+ clientSite->QueryInterface(IID_IOleWindow, (void **) &oleWindow);
+ if (oleWindow != NULL)
+ {
+ HWND hwnd = NULL;
+ oleWindow->GetWindow(&hwnd);
+ if (hwnd != NULL)
+ {
+ HWND hwndGrand = GetParent(hwnd);
+ if (hwndGrand != NULL)
+ {
+ FVCNDATA_NMHDR nmhdr = {0};
+ nmhdr.cbSize = sizeof(FVCNDATA_NMHDR);
+ nmhdr.hwndFrom = hwnd;
+ nmhdr.code = NM_FIREVIEWCHANGE;
+ nmhdr.bAction = FVCA_SENDVIEWCHANGE;
+ nmhdr.bEvent = FVCN_POSTFIRE;
+ SendMessage(hwndGrand, WM_NOTIFY, (WPARAM) nmhdr.hwndFrom, (LPARAM) &nmhdr);
+ }
+ }
+ oleWindow->Release();
+ }
+}
+
+
+void OleImage::Invalidate()
+{
+ if (clientSite == NULL)
+ return;
+
+ IOleWindow *oleWindow = NULL;
+ clientSite->QueryInterface(IID_IOleWindow, (void **) &oleWindow);
+ if (oleWindow != NULL)
+ {
+ HWND hwnd = NULL;
+ oleWindow->GetWindow(&hwnd);
+ if (hwnd != NULL)
+ {
+ InvalidateRect(hwnd, NULL, FALSE);
+ }
+ oleWindow->Release();
+ }
+}
+
+
+void OleImage::SendOnViewChage()
+{
+ if (viewAdviseSink == NULL)
+ return;
+
+ viewAdviseSink->OnViewChange(DVASPECT_CONTENT, -1);
+ if (viewAdvf & ADVF_ONLYONCE)
+ {
+ viewAdviseSink->Release();
+ viewAdviseSink = NULL;
+ }
+}
+
+
+BOOL OleImage::LoadStaticImage()
+{
+ // Load static image
+ DWORD transp;
+ si.hBmp = (HBITMAP) CallService(MS_AV_LOADBITMAP32, (WPARAM) &transp, (LPARAM) filename);
+ if (si.hBmp == NULL)
+ return FALSE;
+
+ BITMAP bmp;
+ if (!GetObject(si.hBmp, sizeof(bmp), &bmp))
+ {
+ DeleteObject(si.hBmp);
+ si.hBmp = NULL;
+ return FALSE;
+ }
+
+ si.transparent = (bmp.bmBitsPixel == 32 && transp);
+ if (si.transparent)
+ PreMultiply(si.hBmp);
+
+ width = bmp.bmWidth;
+ height = bmp.bmHeight;
+
+ return TRUE;
+}
+
+
+BOOL OleImage::LoadAnimatedGif()
+{
+ int x, y;
+
+ FREE_IMAGE_FORMAT fif = fei->FI_GetFileType(filename, 0);
+ if(fif == FIF_UNKNOWN)
+ fif = fei->FI_GetFIFFromFilename(filename);
+
+ ag.multi = fei->FI_OpenMultiBitmap(fif, filename, FALSE, TRUE, FALSE, GIF_LOAD256);
+ if (ag.multi == NULL)
+ return FALSE;
+
+ ag.frameCount = fei->FI_GetPageCount(ag.multi);
+ if (ag.frameCount <= 1)
+ goto ERR;
+
+ if (!AnimatedGifGetData())
+ goto ERR;
+
+ //allocate entire logical area
+ ag.dib = fei->FI_Allocate(width, height, 32, 0, 0, 0);
+ if (ag.dib == NULL)
+ goto ERR;
+
+ //fill with background color to start
+ for (y = 0; y < height; y++)
+ {
+ RGBQUAD *scanline = (RGBQUAD *) fei->FI_GetScanLine(ag.dib, y);
+ for (x = 0; x < width; x++)
+ *scanline++ = ag.background;
+ }
+
+ ag.hbms = (HBITMAP *) malloc(sizeof(HBITMAP) * ag.frameCount);
+ memset(ag.hbms, 0, sizeof(HBITMAP) * ag.frameCount);
+
+ ag.times = (int *) malloc(sizeof(int) * ag.frameCount);
+ memset(ag.times, 0, sizeof(int) * ag.frameCount);
+
+ ag.frame.num = 0;
+
+ return TRUE;
+ERR:
+ fei->FI_CloseMultiBitmap(ag.multi, 0);
+ ag.multi = NULL;
+
+ return FALSE;
+}
+
+
+BOOL OleImage::AnimatedGifGetData()
+{
+ FIBITMAP *page = fei->FI_LockPage(ag.multi, 0);
+ if (page == NULL)
+ return FALSE;
+
+ // Get info
+ FITAG *tag = NULL;
+ if (!fei->FI_GetMetadata(FIMD_ANIMATION, page, "LogicalWidth", &tag))
+ goto ERR;
+ width = *(WORD *)fei->FI_GetTagValue(tag);
+
+ if (!fei->FI_GetMetadata(FIMD_ANIMATION, page, "LogicalHeight", &tag))
+ goto ERR;
+ height = *(WORD *)fei->FI_GetTagValue(tag);
+
+ if (!fei->FI_GetMetadata(FIMD_ANIMATION, page, "Loop", &tag))
+ goto ERR;
+ ag.loop = (*(LONG *)fei->FI_GetTagValue(tag) > 0);
+
+ if (fei->FI_HasBackgroundColor(page))
+ fei->FI_GetBackgroundColor(page, &ag.background);
+
+ fei->FI_UnlockPage(ag.multi, page, FALSE);
+ return TRUE;
+
+ERR:
+ fei->FI_UnlockPage(ag.multi, page, FALSE);
+ return FALSE;
+}
+
+
+void OleImage::AnimatedGifMountFrame()
+{
+ int page = ag.frame.num;
+ if (ag.hbms[page] != NULL)
+ {
+ ag.frame.disposal_method = GIF_DISPOSAL_LEAVE;
+ return;
+ }
+
+ FIBITMAP *dib = fei->FI_LockPage(ag.multi, page);
+ if (dib == NULL)
+ return;
+
+ FITAG *tag = NULL;
+ if (fei->FI_GetMetadata(FIMD_ANIMATION, dib, "FrameLeft", &tag))
+ ag.frame.left = *(WORD *)fei->FI_GetTagValue(tag);
+ else
+ ag.frame.left = 0;
+
+ if (fei->FI_GetMetadata(FIMD_ANIMATION, dib, "FrameTop", &tag))
+ ag.frame.top = *(WORD *)fei->FI_GetTagValue(tag);
+ else
+ ag.frame.top = 0;
+
+ if (fei->FI_GetMetadata(FIMD_ANIMATION, dib, "FrameTime", &tag))
+ ag.times[page] = *(LONG *)fei->FI_GetTagValue(tag);
+ else
+ ag.times[page] = 0;
+
+ if (fei->FI_GetMetadata(FIMD_ANIMATION, dib, "DisposalMethod", &tag))
+ ag.frame.disposal_method = *(BYTE *)fei->FI_GetTagValue(tag);
+ else
+ ag.frame.disposal_method = 0;
+
+ ag.frame.width = fei->FI_GetWidth(dib);
+ ag.frame.height = fei->FI_GetHeight(dib);
+
+
+ //decode page
+ int palSize = fei->FI_GetColorsUsed(dib);
+ RGBQUAD *pal = fei->FI_GetPalette(dib);
+ BOOL have_transparent = FALSE;
+ int transparent_color = -1;
+ if( fei->FI_IsTransparent(dib) ) {
+ int count = fei->FI_GetTransparencyCount(dib);
+ BYTE *table = fei->FI_GetTransparencyTable(dib);
+ for( int i = 0; i < count; i++ ) {
+ if( table[i] == 0 ) {
+ have_transparent = TRUE;
+ transparent_color = i;
+ break;
+ }
+ }
+ }
+
+ //copy page data into logical buffer, with full alpha opaqueness
+ for( int y = 0; y < ag.frame.height; y++ ) {
+ RGBQUAD *scanline = (RGBQUAD *)fei->FI_GetScanLine(ag.dib, height - (y + ag.frame.top) - 1) + ag.frame.left;
+ BYTE *pageline = fei->FI_GetScanLine(dib, ag.frame.height - y - 1);
+ for( int x = 0; x < ag.frame.width; x++ ) {
+ if( !have_transparent || *pageline != transparent_color ) {
+ *scanline = pal[*pageline];
+ scanline->rgbReserved = 255;
+ }
+ scanline++;
+ pageline++;
+ }
+ }
+
+ ag.hbms[page] = fei->FI_CreateHBITMAPFromDIB(ag.dib);
+
+ if (transparent_color)
+ PreMultiply(ag.hbms[page]);
+
+ fei->FI_UnlockPage(ag.multi, dib, FALSE);
+}
+
+
+void OleImage::AnimatedGifDispodeFrame()
+{
+ if (ag.frame.disposal_method == GIF_DISPOSAL_PREVIOUS)
+ {
+ // TODO
+ }
+ else if (ag.frame.disposal_method == GIF_DISPOSAL_BACKGROUND)
+ {
+ for (int y = 0; y < ag.frame.height; y++)
+ {
+ RGBQUAD *scanline = (RGBQUAD *) fei->FI_GetScanLine(ag.dib, height - (y + ag.frame.top) - 1) + ag.frame.left;
+ for (int x = 0; x < ag.frame.width; x++)
+ *scanline++ = ag.background;
+ }
+ }
+}
+
+
+void OleImage::AnimatedGifDeleteTmpValues()
+{
+ if (ag.multi != NULL)
+ {
+ fei->FI_CloseMultiBitmap(ag.multi, 0);
+ ag.multi = NULL;
+ }
+
+ if (ag.dib != NULL)
+ {
+ fei->FI_Unload(ag.dib);
+ ag.dib = NULL;
+ }
+}
+
+
+void OleImage::DestroyAnimatedGif()
+{
+ AnimatedGifDeleteTmpValues();
+
+ if (ag.hbms != NULL)
+ {
+ for (int i = 0; i < ag.frameCount; i++)
+ if (ag.hbms[i] != NULL)
+ DeleteObject(ag.hbms[i]);
+
+ free(ag.hbms);
+ ag.hbms = NULL;
+ }
+
+ if (ag.times != NULL)
+ {
+ free(ag.times);
+ ag.times = NULL;
+ }
+}
+
+
+void OleImage::OnTimer()
+{
+ KillTimer();
+
+ // Move to next frame
+ AnimatedGifDispodeFrame();
+
+ int frame = ag.frame.num + 1;
+ if (frame >= ag.frameCount)
+ {
+ // Don't need fi data no more
+ AnimatedGifDeleteTmpValues();
+ frame = 0;
+ }
+
+ ag.frame.num = frame;
+ ag.started = FALSE;
+
+ OnImageChange();
+}
+
+
+static VOID CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
+{
+ KillTimer(hwnd, idEvent);
+
+ ImageTimerMapType::iterator it = timers.find(idEvent);
+ if (it == timers.end())
+ return;
+
+ OleImage *oimg = it->second;
+ if (oimg == NULL)
+ return;
+
+ oimg->OnTimer();
+}
+
+
+void OleImage::SetTimer(int time)
+{
+ KillTimer();
+ ag.timer = ::SetTimer(0, 0, time, TimerProc);
+ timers[ag.timer] = this;
+}
+
+
+void OleImage::KillTimer()
+{
+ if (ag.timer != NULL)
+ {
+ ::KillTimer(NULL, ag.timer);
+ timers.erase(ag.timer);
+ ag.timer = NULL;
+ }
+}
diff --git a/Plugins/emoticons/OleImage.h b/Plugins/emoticons/OleImage.h
new file mode 100644
index 0000000..78c3e70
--- /dev/null
+++ b/Plugins/emoticons/OleImage.h
@@ -0,0 +1,150 @@
+/*
+Copyright (C) 2008 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+#ifndef __OLEIMAGE_H__
+# define __OLEIMAGE_H__
+
+#include <windows.h>
+
+// {2FD9449B-7EBB-476a-A9DD-AE61382CCE08}
+static const GUID IID_IOleImage = { 0x2fd9449b, 0x7ebb, 0x476a, { 0xa9, 0xdd, 0xae, 0x61, 0x38, 0x2c, 0xce, 0x8 } };
+
+class OleImage : public IOleObject, public IViewObject, public ITooltipData
+{
+public:
+ OleImage(const char *aFilename, const TCHAR *aText, const TCHAR *aTooltip);
+ virtual ~OleImage();
+
+ BOOL ShowDownloadingIcon(BOOL show);
+
+ BOOL isValid() const;
+ const TCHAR * GetText() const;
+ const char * GetFilename() const;
+ void OnTimer();
+
+
+ // IUnknown
+ virtual HRESULT STDMETHODCALLTYPE QueryInterface(/* [in] */ REFIID riid, /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
+ virtual ULONG STDMETHODCALLTYPE AddRef(void);
+ virtual ULONG STDMETHODCALLTYPE Release(void);
+
+ // IOleObject
+ virtual HRESULT STDMETHODCALLTYPE SetClientSite(/* [unique][in] */ IOleClientSite *pClientSite);
+ virtual HRESULT STDMETHODCALLTYPE GetClientSite(/* [out] */ IOleClientSite **ppClientSite);
+ virtual HRESULT STDMETHODCALLTYPE SetHostNames(/* [in] */ LPCOLESTR szContainerApp, /* [unique][in] */ LPCOLESTR szContainerObj);
+ virtual HRESULT STDMETHODCALLTYPE Close(/* [in] */ DWORD dwSaveOption);
+ virtual HRESULT STDMETHODCALLTYPE SetMoniker(/* [in] */ DWORD dwWhichMoniker, /* [unique][in] */ IMoniker *pmk);
+ virtual HRESULT STDMETHODCALLTYPE GetMoniker(/* [in] */ DWORD dwAssign, /* [in] */ DWORD dwWhichMoniker, /* [out] */ IMoniker **ppmk);
+ virtual HRESULT STDMETHODCALLTYPE InitFromData(/* [unique][in] */ IDataObject *pDataObject, /* [in] */ BOOL fCreation, /* [in] */ DWORD dwReserved);
+ virtual HRESULT STDMETHODCALLTYPE GetClipboardData(/* [in] */ DWORD dwReserved, /* [out] */ IDataObject **ppDataObject);
+ virtual HRESULT STDMETHODCALLTYPE DoVerb(/* [in] */ LONG iVerb, /* [unique][in] */ LPMSG lpmsg, /* [unique][in] */ IOleClientSite *pActiveSite, /* [in] */ LONG lindex, /* [in] */ HWND hwndParent, /* [unique][in] */ LPCRECT lprcPosRect);
+ virtual HRESULT STDMETHODCALLTYPE EnumVerbs(/* [out] */ IEnumOLEVERB **ppEnumOleVerb);
+ virtual HRESULT STDMETHODCALLTYPE Update(void);
+ virtual HRESULT STDMETHODCALLTYPE IsUpToDate(void);
+ virtual HRESULT STDMETHODCALLTYPE GetUserClassID(/* [out] */ CLSID *pClsid);
+ virtual HRESULT STDMETHODCALLTYPE GetUserType(/* [in] */ DWORD dwFormOfType, /* [out] */ LPOLESTR *pszUserType);
+ virtual HRESULT STDMETHODCALLTYPE SetExtent(/* [in] */ DWORD dwDrawAspect, /* [in] */ SIZEL *psizel);
+ virtual HRESULT STDMETHODCALLTYPE GetExtent(/* [in] */ DWORD dwDrawAspect, /* [out] */ SIZEL *psizel);
+ virtual HRESULT STDMETHODCALLTYPE Advise(/* [unique][in] */ IAdviseSink *pAdvSink, /* [out] */ DWORD *pdwConnection);
+ virtual HRESULT STDMETHODCALLTYPE Unadvise(/* [in] */ DWORD dwConnection);
+ virtual HRESULT STDMETHODCALLTYPE EnumAdvise(/* [out] */ IEnumSTATDATA **ppenumAdvise);
+ virtual HRESULT STDMETHODCALLTYPE GetMiscStatus(/* [in] */ DWORD dwAspect, /* [out] */ DWORD *pdwStatus);
+ virtual HRESULT STDMETHODCALLTYPE SetColorScheme(/* [in] */ LOGPALETTE *pLogpal);
+
+ // IViewObject
+ virtual /* [local] */ HRESULT STDMETHODCALLTYPE Draw(/* [in] */ DWORD dwDrawAspect, /* [in] */ LONG lindex, /* [unique][in] */ void *pvAspect, /* [unique][in] */ DVTARGETDEVICE *ptd, /* [in] */ HDC hdcTargetDev, /* [in] */ HDC hdcDraw, /* [in] */ LPCRECTL lprcBounds, /* [unique][in] */ LPCRECTL lprcWBounds, /* [in] */ BOOL ( STDMETHODCALLTYPE *pfnContinue )(ULONG_PTR dwContinue), /* [in] */ ULONG_PTR dwContinue);
+ virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetColorSet(/* [in] */ DWORD dwDrawAspect, /* [in] */ LONG lindex, /* [unique][in] */ void *pvAspect, /* [unique][in] */ DVTARGETDEVICE *ptd, /* [in] */ HDC hicTargetDev, /* [out] */ LOGPALETTE **ppColorSet);
+ virtual /* [local] */ HRESULT STDMETHODCALLTYPE Freeze(/* [in] */ DWORD dwDrawAspect, /* [in] */ LONG lindex, /* [unique][in] */ void *pvAspect, /* [out] */ DWORD *pdwFreeze);
+ virtual HRESULT STDMETHODCALLTYPE Unfreeze(/* [in] */ DWORD dwFreeze);
+ virtual HRESULT STDMETHODCALLTYPE SetAdvise(/* [in] */ DWORD aspects, /* [in] */ DWORD advf, /* [unique][in] */ IAdviseSink *pAdvSink);
+ virtual /* [local] */ HRESULT STDMETHODCALLTYPE GetAdvise(/* [unique][out] */ DWORD *pAspects, /* [unique][out] */ DWORD *pAdvf, /* [out] */ IAdviseSink **ppAdvSink);
+
+ // ITooltipData
+ virtual HRESULT STDMETHODCALLTYPE SetTooltip(/* [in] */ BSTR aTooltip);
+ virtual HRESULT STDMETHODCALLTYPE GetTooltip(/* [out, retval] */ BSTR * aTooltip);
+
+protected:
+ char *filename;
+ char *originalFilename;
+ TCHAR *text;
+ BSTR tooltip;
+ int width;
+ int height;
+ BOOL animated;
+ BOOL closed;
+
+ LONG refCount;
+
+ IOleClientSite *clientSite;
+ IOleAdviseHolder *oleAdviseHolder;
+ IAdviseSink *viewAdviseSink;
+ DWORD viewAdvf;
+ SIZEL sizel;
+
+ BOOL LoadImages();
+ void DestroyImages();
+ void CalcSize();
+ void SetTimer(int time);
+ void KillTimer();
+ void Invalidate();
+ void SendOnViewChage();
+ void OnImageChange();
+ void NotifyHpp();
+
+ BOOL LoadStaticImage();
+ BOOL LoadAnimatedGif();
+ BOOL AnimatedGifGetData();
+ void AnimatedGifMountFrame();
+ void AnimatedGifDispodeFrame();
+ void AnimatedGifDeleteTmpValues();
+ void DestroyAnimatedGif();
+
+ struct
+ {
+ HBITMAP hBmp;
+ BOOL transparent;
+ } si;
+
+ struct
+ {
+ UINT timer;
+ HBITMAP *hbms;
+ int *times;
+
+ FIMULTIBITMAP *multi;
+ FIBITMAP *dib;
+ int frameCount;
+ BOOL loop;
+ RGBQUAD background;
+ BOOL started;
+
+ struct {
+ int num;
+ int top;
+ int left;
+ int width;
+ int height;
+ int disposal_method;
+ } frame;
+ } ag;
+};
+
+
+
+#endif // __OLEIMAGE_H__
diff --git a/Plugins/emoticons/commons.h b/Plugins/emoticons/commons.h
new file mode 100644
index 0000000..990c99e
--- /dev/null
+++ b/Plugins/emoticons/commons.h
@@ -0,0 +1,218 @@
+/*
+Copyright (C) 2008 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __COMMONS_H__
+# define __COMMONS_H__
+
+
+#define OEMRESOURCE
+#define _WIN32_WINNT 0x0400
+#include <windows.h>
+#include <commctrl.h>
+#include <tchar.h>
+#include <stdio.h>
+#include <time.h>
+#include <richedit.h>
+#include <tom.h>
+#include <richole.h>
+
+
+// Disable "...truncated to '255' characters in the debug information" warnings
+#pragma warning(disable: 4786)
+
+#include <map>
+#include <string>
+using namespace std;
+
+
+// Miranda headers
+#define MIRANDA_VER 0x0700
+#include <win2k.h>
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_system_cpp.h>
+#include <m_protocols.h>
+#include <m_protosvc.h>
+#include <m_clist.h>
+#include <m_contacts.h>
+#include <m_langpack.h>
+#include <m_database.h>
+#include <m_options.h>
+#include <m_utils.h>
+#include <m_updater.h>
+#include <m_metacontacts.h>
+#include <m_popup.h>
+#include <m_history.h>
+#include <m_message.h>
+#include <m_folders.h>
+#include <m_icolib.h>
+#include <m_avatars.h>
+#include <m_imgsrvc.h>
+#include <m_anismiley.h>
+#include <anismiley.tlh>
+#include <m_smileyadd.h>
+#include <m_customsmileys.h>
+
+#include "../utils/mir_memory.h"
+#include "../utils/mir_options.h"
+#include "../utils/mir_icons.h"
+#include "../utils/mir_buffer.h"
+
+#include "resource.h"
+#include "m_emoticons.h"
+#include "options.h"
+#include "selwin.h"
+#include "OleImage.h"
+
+
+#define MODULE_NAME "Emoticons"
+
+
+// Global Variables
+extern HINSTANCE hInst;
+extern PLUGINLINK *pluginLink;
+extern FI_INTERFACE *fei;
+
+
+#define MIR_FREE(_X_) { mir_free(_X_); _X_ = NULL; }
+#define MAX_REGS(_A_) ( sizeof(_A_) / sizeof(_A_[0]) )
+
+struct EmoticonPack;
+
+struct EmoticonImage
+{
+ EmoticonPack *pack;
+ char *name;
+ char *relPath;
+ char *module;
+
+ // For selection window
+ HBITMAP img;
+ BOOL transparent;
+
+ EmoticonImage() : name(0), relPath(0), img(0), module(0) {}
+ ~EmoticonImage();
+
+ void Load(int &max_height, int &max_width);
+ void Release();
+ BOOL isAvaiable();
+ BOOL isAvaiableFor(char *nodule);
+};
+
+struct Emoticon
+{
+ char *name;
+ TCHAR *description;
+ LIST<TCHAR> texts;
+ EmoticonImage *img;
+
+ // For selection window
+ HWND tt;
+
+ Emoticon() : name(0), description(0), texts(20), img(0), tt(0) {}
+ ~Emoticon();
+};
+
+struct CustomEmoticon
+{
+ TCHAR *text;
+ char *path;
+ BOOL downloading;
+
+ CustomEmoticon() : text(0), path(0), downloading(FALSE) {}
+};
+
+struct Module
+{
+ char *name;
+ TCHAR *path;
+ LIST<Emoticon> emoticons;
+
+ Module() : name(0), path(0), emoticons(20) {}
+ ~Module();
+};
+
+
+struct EmoticonPack
+{
+ char *name;
+ TCHAR *description;
+ char *path;
+ TCHAR *creator;
+ TCHAR *updater_URL;
+ LIST<EmoticonImage> images;
+
+ EmoticonPack() : name(0), path(0), creator(0), updater_URL(0), images(20) {}
+ ~EmoticonPack();
+};
+
+struct RichEditCtrl
+{
+ HWND hwnd;
+ IRichEditOle *ole;
+ ITextDocument *textDocument;
+ WNDPROC old_edit_proc;
+ BOOL received_stream_in;
+ int stream_in_pos;
+ BOOL sending;
+};
+
+struct Contact
+{
+ HANDLE hContact;
+ LIST<CustomEmoticon> emoticons;
+ int lastId;
+
+ Contact(HANDLE aHContact) : hContact(aHContact), emoticons(5), lastId(-1) {}
+};
+
+struct Dialog
+{
+ Contact *contact;
+ Module *module;
+
+ HWND hwnd_owner;
+ WNDPROC owner_old_edit_proc;
+
+ RichEditCtrl input;
+ RichEditCtrl log;
+};
+
+extern LIST<Module> modules;
+extern LIST<EmoticonPack> packs;
+
+extern TCHAR protocolsFolder[1024];
+extern TCHAR emoticonPacksFolder[1024];
+
+// SRMM messages
+#define DM_REMAKELOG (WM_USER + 11)
+#define DM_APPENDTOLOG (WM_USER + 17)
+
+
+HANDLE GetRealContact(HANDLE hContact);
+Module *GetModule(const char *name);
+
+void FillModuleImages(EmoticonPack *pack);
+
+
+
+
+
+#endif // __COMMONS_H__
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/Tango.mep b/Plugins/emoticons/data/Customize/Emoticons/Tango/Tango.mep
new file mode 100644
index 0000000..213905d
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/Tango.mep
@@ -0,0 +1,2 @@
+Name: Tango emoticons
+Creator: Hylke \ No newline at end of file
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/act-up.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/act-up.png
new file mode 100644
index 0000000..a73b4f5
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/act-up.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/airplane.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/airplane.png
new file mode 100644
index 0000000..89b45ef
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/airplane.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/alien.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/alien.png
new file mode 100644
index 0000000..ca83124
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/alien.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/angel.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/angel.png
new file mode 100644
index 0000000..ad98a51
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/angel.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/angry.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/angry.png
new file mode 100644
index 0000000..8558f46
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/angry.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/arrogant.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/arrogant.png
new file mode 100644
index 0000000..42b85ff
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/arrogant.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/bashful.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/bashful.png
new file mode 100644
index 0000000..c0cca0b
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/bashful.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/beat-up.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/beat-up.png
new file mode 100644
index 0000000..ac1b463
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/beat-up.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/beauty.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/beauty.png
new file mode 100644
index 0000000..30411f6
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/beauty.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/beer.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/beer.png
new file mode 100644
index 0000000..e955770
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/beer.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/blowkiss.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/blowkiss.png
new file mode 100644
index 0000000..461204f
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/blowkiss.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/bomb.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/bomb.png
new file mode 100644
index 0000000..9f28ff0
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/bomb.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/boring.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/boring.png
new file mode 100644
index 0000000..0d0243a
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/boring.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/bowl.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/bowl.png
new file mode 100644
index 0000000..d236b07
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/bowl.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/brb.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/brb.png
new file mode 100644
index 0000000..3afe83e
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/brb.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/bug.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/bug.png
new file mode 100644
index 0000000..0226f88
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/bug.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/bye.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/bye.png
new file mode 100644
index 0000000..7e4e7de
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/bye.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/cake.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/cake.png
new file mode 100644
index 0000000..5cf3dd6
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/cake.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/call-me.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/call-me.png
new file mode 100644
index 0000000..230da3e
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/call-me.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/camera.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/camera.png
new file mode 100644
index 0000000..86ae7c1
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/camera.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/can.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/can.png
new file mode 100644
index 0000000..e4792cc
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/can.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/car.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/car.png
new file mode 100644
index 0000000..0e605fa
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/car.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/cat.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/cat.png
new file mode 100644
index 0000000..9454c7b
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/cat.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/chicken.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/chicken.png
new file mode 100644
index 0000000..8356dbf
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/chicken.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/cigarette.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/cigarette.png
new file mode 100644
index 0000000..1e0b15c
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/cigarette.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/clap.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/clap.png
new file mode 100644
index 0000000..80b0ae1
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/clap.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/clock.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/clock.png
new file mode 100644
index 0000000..4de10e0
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/clock.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/cloudy.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/cloudy.png
new file mode 100644
index 0000000..4202a0e
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/cloudy.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/clover.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/clover.png
new file mode 100644
index 0000000..d178c40
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/clover.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/clown.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/clown.png
new file mode 100644
index 0000000..bfc9552
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/clown.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/coffee.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/coffee.png
new file mode 100644
index 0000000..e80fee3
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/coffee.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/coins.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/coins.png
new file mode 100644
index 0000000..2c28453
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/coins.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/computer.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/computer.png
new file mode 100644
index 0000000..c0a3f90
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/computer.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/confused.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/confused.png
new file mode 100644
index 0000000..e1a76fc
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/confused.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/console.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/console.png
new file mode 100644
index 0000000..46e4287
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/console.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/cow.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/cow.png
new file mode 100644
index 0000000..62657da
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/cow.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/cowboy.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/cowboy.png
new file mode 100644
index 0000000..35e71af
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/cowboy.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/crying.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/crying.png
new file mode 100644
index 0000000..016b82e
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/crying.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/curl-lip.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/curl-lip.png
new file mode 100644
index 0000000..bf12d34
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/curl-lip.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/curse.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/curse.png
new file mode 100644
index 0000000..f21227a
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/curse.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/cute.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/cute.png
new file mode 100644
index 0000000..ca6b401
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/cute.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/dance.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/dance.png
new file mode 100644
index 0000000..709701d
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/dance.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/dazed.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/dazed.png
new file mode 100644
index 0000000..db277fb
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/dazed.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/desire.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/desire.png
new file mode 100644
index 0000000..b6a9174
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/desire.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/devilish.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/devilish.png
new file mode 100644
index 0000000..3e043d0
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/devilish.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/disapointed.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/disapointed.png
new file mode 100644
index 0000000..b2aced9
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/disapointed.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/disdain.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/disdain.png
new file mode 100644
index 0000000..bca43cc
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/disdain.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/doctor.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/doctor.png
new file mode 100644
index 0000000..e7eb6ee
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/doctor.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/dog.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/dog.png
new file mode 100644
index 0000000..8e9b455
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/dog.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/doh.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/doh.png
new file mode 100644
index 0000000..d5cd84c
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/doh.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/dont-know.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/dont-know.png
new file mode 100644
index 0000000..df2b647
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/dont-know.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/drink.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/drink.png
new file mode 100644
index 0000000..46412be
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/drink.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/drool.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/drool.png
new file mode 100644
index 0000000..b9463ea
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/drool.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/eat.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/eat.png
new file mode 100644
index 0000000..6dfa2cc
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/eat.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/embarrassed.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/embarrassed.png
new file mode 100644
index 0000000..93c1c26
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/embarrassed.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/excruciating.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/excruciating.png
new file mode 100644
index 0000000..816bf4f
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/excruciating.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/eyeroll.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/eyeroll.png
new file mode 100644
index 0000000..ff4aa97
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/eyeroll.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/female.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/female.png
new file mode 100644
index 0000000..f758c2b
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/female.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/film.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/film.png
new file mode 100644
index 0000000..2d9b0b5
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/film.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/fingers-crossed.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/fingers-crossed.png
new file mode 100644
index 0000000..6494707
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/fingers-crossed.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/foot-in-mouth.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/foot-in-mouth.png
new file mode 100644
index 0000000..888c587
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/foot-in-mouth.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/freaked-out.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/freaked-out.png
new file mode 100644
index 0000000..3bb6d58
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/freaked-out.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/ghost.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/ghost.png
new file mode 100644
index 0000000..a58efa5
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/ghost.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/giggle.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/giggle.png
new file mode 100644
index 0000000..e583178
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/giggle.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/glass-cool.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/glass-cool.png
new file mode 100644
index 0000000..6fdb5fe
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/glass-cool.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/glass-nerdy.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/glass-nerdy.png
new file mode 100644
index 0000000..04af3c7
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/glass-nerdy.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/go-away.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/go-away.png
new file mode 100644
index 0000000..efc98af
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/go-away.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/goat.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/goat.png
new file mode 100644
index 0000000..dfd4dc3
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/goat.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/hammer.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/hammer.png
new file mode 100644
index 0000000..53098ac
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/hammer.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/handcuffs.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/handcuffs.png
new file mode 100644
index 0000000..3463bdf
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/handcuffs.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/handshake.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/handshake.png
new file mode 100644
index 0000000..5c6d6a5
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/handshake.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/highfive.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/highfive.png
new file mode 100644
index 0000000..d49f02f
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/highfive.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/hug-left.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/hug-left.png
new file mode 100644
index 0000000..3e84f68
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/hug-left.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/hug-right.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/hug-right.png
new file mode 100644
index 0000000..9c70403
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/hug-right.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/hungry.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/hungry.png
new file mode 100644
index 0000000..d023d35
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/hungry.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/hypnotized.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/hypnotized.png
new file mode 100644
index 0000000..62823ce
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/hypnotized.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/in-love.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/in-love.png
new file mode 100644
index 0000000..7fdedb5
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/in-love.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/island.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/island.png
new file mode 100644
index 0000000..a335e3f
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/island.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/jump.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/jump.png
new file mode 100644
index 0000000..ad00de1
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/jump.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/kiss.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/kiss.png
new file mode 100644
index 0000000..8d0d2e8
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/kiss.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/kissed.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/kissed.png
new file mode 100644
index 0000000..8d0d2e8
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/kissed.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/knife.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/knife.png
new file mode 100644
index 0000000..6db80de
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/knife.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/lamp.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/lamp.png
new file mode 100644
index 0000000..0431d75
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/lamp.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/lashes.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/lashes.png
new file mode 100644
index 0000000..7fc816b
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/lashes.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/laugh.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/laugh.png
new file mode 100644
index 0000000..fdb4f50
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/laugh.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/liquor.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/liquor.png
new file mode 100644
index 0000000..cd509c9
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/liquor.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/loser.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/loser.png
new file mode 100644
index 0000000..568f2ca
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/loser.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/love-over.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/love-over.png
new file mode 100644
index 0000000..fc7ad6f
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/love-over.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/love.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/love.png
new file mode 100644
index 0000000..5171dee
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/love.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/lying.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/lying.png
new file mode 100644
index 0000000..eff40d0
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/lying.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/mad-tongue.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/mad-tongue.png
new file mode 100644
index 0000000..cdaa32b
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/mad-tongue.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/mail.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/mail.png
new file mode 100644
index 0000000..027bdb0
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/mail.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/male.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/male.png
new file mode 100644
index 0000000..4608f0d
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/male.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/mean.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/mean.png
new file mode 100644
index 0000000..a6b1651
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/mean.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/meeting.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/meeting.png
new file mode 100644
index 0000000..f2a0e5e
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/meeting.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/mobile.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/mobile.png
new file mode 100644
index 0000000..5078153
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/mobile.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/moneymouth.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/moneymouth.png
new file mode 100644
index 0000000..ef2acf1
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/moneymouth.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/monkey.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/monkey.png
new file mode 100644
index 0000000..dfc05f5
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/monkey.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/moon.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/moon.png
new file mode 100644
index 0000000..42a41b3
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/moon.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/msn.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/msn.png
new file mode 100644
index 0000000..97977f2
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/msn.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/music.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/music.png
new file mode 100644
index 0000000..5990ae5
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/music.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/nailbiting.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/nailbiting.png
new file mode 100644
index 0000000..bd82680
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/nailbiting.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/neutral.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/neutral.png
new file mode 100644
index 0000000..c9fc926
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/neutral.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/no.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/no.png
new file mode 100644
index 0000000..07fb09b
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/no.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/on-the-phone.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/on-the-phone.png
new file mode 100644
index 0000000..0fef0d1
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/on-the-phone.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/party.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/party.png
new file mode 100644
index 0000000..bcc7a4f
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/party.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/peace.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/peace.png
new file mode 100644
index 0000000..ffeab9d
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/peace.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/phone.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/phone.png
new file mode 100644
index 0000000..83b614f
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/phone.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/pick-fight.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/pick-fight.png
new file mode 100644
index 0000000..c741907
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/pick-fight.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/pig.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/pig.png
new file mode 100644
index 0000000..1dc5c1f
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/pig.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/pill.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/pill.png
new file mode 100644
index 0000000..04d326a
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/pill.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/pissed-off.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/pissed-off.png
new file mode 100644
index 0000000..a1c8c8c
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/pissed-off.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/pizza.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/pizza.png
new file mode 100644
index 0000000..461f218
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/pizza.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/plate.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/plate.png
new file mode 100644
index 0000000..45036b3
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/plate.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/poop.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/poop.png
new file mode 100644
index 0000000..fe05f85
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/poop.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/pray.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/pray.png
new file mode 100644
index 0000000..c7f5e87
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/pray.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/present.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/present.png
new file mode 100644
index 0000000..cf39af2
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/present.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/pumpkin.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/pumpkin.png
new file mode 100644
index 0000000..847e28a
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/pumpkin.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/qq.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/qq.png
new file mode 100644
index 0000000..cf5a02a
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/qq.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/question.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/question.png
new file mode 100644
index 0000000..fc657b4
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/question.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/quiet.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/quiet.png
new file mode 100644
index 0000000..9e6f038
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/quiet.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/rain.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/rain.png
new file mode 100644
index 0000000..a67718e
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/rain.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/rainbow.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/rainbow.png
new file mode 100644
index 0000000..344fdb5
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/rainbow.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/rock.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/rock.png
new file mode 100644
index 0000000..709701d
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/rock.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/rose-dead.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/rose-dead.png
new file mode 100644
index 0000000..8cbccc4
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/rose-dead.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/rose.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/rose.png
new file mode 100644
index 0000000..ff7180e
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/rose.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/rotfl.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/rotfl.png
new file mode 100644
index 0000000..9f985a2
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/rotfl.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/sad.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/sad.png
new file mode 100644
index 0000000..643fd43
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/sad.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/sarcastic.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/sarcastic.png
new file mode 100644
index 0000000..ece6dd5
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/sarcastic.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/scream.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/scream.png
new file mode 100644
index 0000000..816bf4f
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/scream.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/search.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/search.png
new file mode 100644
index 0000000..d61cebb
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/search.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/secret.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/secret.png
new file mode 100644
index 0000000..30703ea
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/secret.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/shame.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/shame.png
new file mode 100644
index 0000000..fcdf942
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/shame.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/sheep.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/sheep.png
new file mode 100644
index 0000000..8dffc36
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/sheep.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/shock.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/shock.png
new file mode 100644
index 0000000..2befb02
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/shock.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/shout.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/shout.png
new file mode 100644
index 0000000..c7aa7a9
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/shout.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/shut-mouth.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/shut-mouth.png
new file mode 100644
index 0000000..c98a297
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/shut-mouth.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/sick.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/sick.png
new file mode 100644
index 0000000..777e6fd
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/sick.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/silly.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/silly.png
new file mode 100644
index 0000000..b944b7e
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/silly.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/skeleton.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/skeleton.png
new file mode 100644
index 0000000..f59540d
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/skeleton.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/skywalker.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/skywalker.png
new file mode 100644
index 0000000..227cd08
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/skywalker.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/sleepy.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/sleepy.png
new file mode 100644
index 0000000..2544903
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/sleepy.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/smile-big.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/smile-big.png
new file mode 100644
index 0000000..8d2cc88
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/smile-big.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/smile.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/smile.png
new file mode 100644
index 0000000..7fa977f
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/smile.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/smirk.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/smirk.png
new file mode 100644
index 0000000..77e97ee
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/smirk.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/snail.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/snail.png
new file mode 100644
index 0000000..c2e97c8
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/snail.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/snicker.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/snicker.png
new file mode 100644
index 0000000..67e0936
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/snicker.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/snowman.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/snowman.png
new file mode 100644
index 0000000..9fec7d7
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/snowman.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/soccerball.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/soccerball.png
new file mode 100644
index 0000000..157a6fd
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/soccerball.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/soldier.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/soldier.png
new file mode 100644
index 0000000..0f38d16
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/soldier.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/star.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/star.png
new file mode 100644
index 0000000..6e3c436
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/star.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/starving.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/starving.png
new file mode 100644
index 0000000..d023d35
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/starving.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/stop.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/stop.png
new file mode 100644
index 0000000..efc98af
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/stop.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/struggle.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/struggle.png
new file mode 100644
index 0000000..59b22a4
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/struggle.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/sun.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/sun.png
new file mode 100644
index 0000000..b3c2663
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/sun.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/sweat.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/sweat.png
new file mode 100644
index 0000000..6cde5ce
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/sweat.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/talktohand.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/talktohand.png
new file mode 100644
index 0000000..dedf1da
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/talktohand.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/teeth.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/teeth.png
new file mode 100644
index 0000000..8b20c00
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/teeth.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/terror.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/terror.png
new file mode 100644
index 0000000..104d012
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/terror.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/thinking.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/thinking.png
new file mode 100644
index 0000000..9d1d752
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/thinking.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/thunder.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/thunder.png
new file mode 100644
index 0000000..282e74a
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/thunder.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/time-out.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/time-out.png
new file mode 100644
index 0000000..49d3535
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/time-out.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/tongue.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/tongue.png
new file mode 100644
index 0000000..144318d
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/tongue.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/tremble.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/tremble.png
new file mode 100644
index 0000000..3a39e87
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/tremble.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/turtle.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/turtle.png
new file mode 100644
index 0000000..505d5b2
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/turtle.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/tv.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/tv.png
new file mode 100644
index 0000000..592f6cc
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/tv.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/umbrella.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/umbrella.png
new file mode 100644
index 0000000..68f6615
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/umbrella.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/usa.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/usa.png
new file mode 100644
index 0000000..aff8637
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/usa.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/vampire.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/vampire.png
new file mode 100644
index 0000000..a2ae6e3
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/vampire.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/victory.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/victory.png
new file mode 100644
index 0000000..d0b635e
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/victory.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/waiting.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/waiting.png
new file mode 100644
index 0000000..ec7d9de
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/waiting.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/watermelon.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/watermelon.png
new file mode 100644
index 0000000..4a201d5
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/watermelon.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/weep.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/weep.png
new file mode 100644
index 0000000..51219c1
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/weep.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/wilt.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/wilt.png
new file mode 100644
index 0000000..bdcf85c
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/wilt.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/wink.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/wink.png
new file mode 100644
index 0000000..662baa8
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/wink.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/worship.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/worship.png
new file mode 100644
index 0000000..86315a3
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/worship.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/yawn.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/yawn.png
new file mode 100644
index 0000000..65f7c77
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/yawn.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/yes.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/yes.png
new file mode 100644
index 0000000..127d073
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/yes.png
Binary files differ
diff --git a/Plugins/emoticons/data/Customize/Emoticons/Tango/yin-yang.png b/Plugins/emoticons/data/Customize/Emoticons/Tango/yin-yang.png
new file mode 100644
index 0000000..4d3f970
--- /dev/null
+++ b/Plugins/emoticons/data/Customize/Emoticons/Tango/yin-yang.png
Binary files differ
diff --git a/Plugins/emoticons/data/Plugins/Emoticons/Default.emo b/Plugins/emoticons/data/Plugins/Emoticons/Default.emo
new file mode 100644
index 0000000..9eeaaec
--- /dev/null
+++ b/Plugins/emoticons/data/Plugins/Emoticons/Default.emo
@@ -0,0 +1,16 @@
+# Default emoticons
+
+"smile" = "Smile", ":-)" ":)"
+"laugh" = "Laught", ":-D" ":D"
+"wink" = "Wink", ";-)" ";)"
+"tongue" = "Tongue", ":-P" ":P" "
+"glass-cool" = "Glass", "8-)" "8)"
+"sad" = "Sad", ":-(" ":("
+"crying" = "Crying", ":'("
+"shock" = "Shocked", ":-O" ":O"
+"confused" = "Confused", ":-S" ":S"
+"neutral" = "Neutral", ":-|" ":|"
+"thinking" = "Thinking", ":-/" ":/" ":-\\" ":\\"
+"devilish" = "Devil", "}:-)" "}:)"
+"angel" = "Angel", "O:-)" "O:)" "0:-)" "0:)"
+"silly" = "Silly", "%)" \ No newline at end of file
diff --git a/Plugins/emoticons/data/Plugins/Emoticons/ICQ.emo b/Plugins/emoticons/data/Plugins/Emoticons/ICQ.emo
new file mode 100644
index 0000000..687a362
--- /dev/null
+++ b/Plugins/emoticons/data/Plugins/Emoticons/ICQ.emo
@@ -0,0 +1,30 @@
+# ICQ protocol emoticons
+
+"smile" = "Smile", ":-)" ":)"
+"neutral" = "Nothing to say", ":-$" ":-|"
+"sad" = "Sad", ":-(" ":("
+"shock" = "Surprised", "=-O" "=-o" ":-O" ":-o"
+"wink" = "Blinking", ";-)" ";)"
+"glass-cool" = "Cool", "8-)" "8)"
+"tongue" = "Tongue out", ":-P" ":P" ":p" ":-p"
+"music" = "Listening to music", "[:-}"
+"laugh" = "Laughing", "*JOKINGLY*" "*jokingly*"
+"sleepy" = "Falling asleep", "*TIRED*" "*tired*"
+"crying" = "Crying", ":'-(" ":'("
+"sick" = "Gross", ":-!"
+"stop" = "Stop", "*STOP*" "*stop*"
+"kissed" = "Kissed", "*KISSED*" "*kissed*"
+"kiss" = "Kiss", ":-{}" ":-*"
+"blowkiss" = "Kissing", "*KISSING*" "*kissing*"
+"embarrassed" = "Blushing", ":-["
+"devilish" = "Devil", "]:->"
+"angel" = "Angel", "O:-)"
+"rose" = "Thank you", "@}->--"
+"shut-mouth" = "Can't say / Shut up", ":-X" ":X" ":-x" ":x"
+"bomb" = "Bomb", "@="
+"thinking" = "Mad", ":-/" ":-\\"
+"yes" = "Thumbs up", "*THUMBS UP*" "*thumbs up*"
+"scream" = "Scream", ":-@" ">:o" ">:O"
+"beer" = "Drinking", "*DRINK*" "*drink*"
+"rotfl" = "Laughing out loud (LOL)", ":-D" ":D" ":-d" ":d"
+"in-love" = "In love", "*IN LOVE*" "*in love*"
diff --git a/Plugins/emoticons/data/Plugins/Emoticons/JGMAIL.emo b/Plugins/emoticons/data/Plugins/Emoticons/JGMAIL.emo
new file mode 100644
index 0000000..8f0f7e1
--- /dev/null
+++ b/Plugins/emoticons/data/Plugins/Emoticons/JGMAIL.emo
@@ -0,0 +1,19 @@
+# Google Talk protocol emoticons
+
+"smile" = "Smile", ":)" ":-)" "=)"
+"laugh" = "Grin", ":D" ":-D" "=D"
+"wink" = "Wink", ";)" ";-)" ";^)"
+"crying" = "Cry", ":'("
+"shock" = "Shocked", ":-o"
+"thinking" = "Slant", ":-/"
+"dazed" = "Angry", "x-("
+"sad" = "Frown", ":(" ":-("
+"glass-cool" = "Cool", "B-)"
+"tongue" = "Tongue", ":P" ":-P"
+"love" = "Heart", "<3"
+"neutral" = "Straight Face", ":-|"
+"monkey" = "It's a Monkey!", ":(|)"
+"rock" = "Rock out", "\\m/"
+"bell" = "Cowbell", "+/'\\"
+"devilish" = "Devil", "}:-)" "}:)"
+"doh" = "Wince", ">.<" \ No newline at end of file
diff --git a/Plugins/emoticons/data/Plugins/Emoticons/MSN.emo b/Plugins/emoticons/data/Plugins/Emoticons/MSN.emo
new file mode 100644
index 0000000..21cccff
--- /dev/null
+++ b/Plugins/emoticons/data/Plugins/Emoticons/MSN.emo
@@ -0,0 +1,83 @@
+# MSN protocol emoticons
+
+"smile" = "Smile", ":)" ":-)"
+"laugh" = "Open-mouthed smile", ":D" ":-D" ":d" ":-d"
+"wink" = "", ";)" ";-)"
+"shock" = "Surprised smile", ":-O" ":o" ":O" ":-o"
+"tongue" = "Smile with tongue out", ":P" ":-P" ":p" ":-p"
+"glass-cool" = "Hot smile", "(H)" "(h)"
+"angry" = "Angry smile", ":@" ":-@"
+"confused" = "Confused smile", ":S" ":-S" ":s" ":-s"
+"embarrassed" = "Embarrassed smile", ":$" ":-$"
+"sad" = "Sad smile", ":(" ":-("
+"crying" = "", ":'("
+"neutral" = "Disappointed smile", ":|" ":-|"
+"devilish" = "Devil", "(6)"
+"angel" = "Angel", "(A)" "(a)"
+"teeth" = "Baring teeth smile", "8o|"
+"glass-nerdy" = "Nerd smile", "8-|"
+"sick" = "Sick smile", "+o("
+"party" = "", "<:o)"
+"sleepy" = "", "|-)"
+"thinking" = "Settings", "*-)"
+"quiet" = "Don't tell anyone smile", ":-#"
+"secret" = "Secret telling smile", ":-*"
+"sarcastic" = "Sarcastic smile", "^o)"
+"eyeroll" = "Sign in to Messenger", "8-)"
+"love" = "Red heart", "(L)" "(l)"
+"love-over" = "Broken heart", "(U)" "(u)"
+"msn" = "MSN Messenger", "(M)" "(m)"
+"cat" = "Cat face", "(@)"
+"dog" = "Dog face", "(&)"
+"snail" = "Snail", "(sn)"
+"sheep" = "Black sheep", "(bah)"
+"moon" = "Sleeping half-moon", "(S)"
+"star" = "Star", "(*)"
+"sun" = "Sun", "(#)"
+"rainbow" = "Rainbow", "(R)" "(r)"
+"hug-left" = "Left hug", "({)"
+"hug-right" = "Right hug", "(})"
+"kiss" = "Red lips", "(K)" "(k)"
+"rose" = "Red rose", "(F)" "(f)"
+"rose-dead" = "Wilted rose", "(W)" "(w)"
+"clock" = "Clock", "(O)" "(o)"
+"film" = "Filmstrip", "(~)"
+"music" = "Note", "(8)"
+"mail" = "E-mail", "(E)" "(e)"
+"present" = "Gift with a bow", "(G)" "(g)"
+"cake" = "", "(^)"
+"camera" = "Camera", "(P)" "(p)"
+"lamp" = "Light bulb", "(I)" "(i)"
+"coffee" = "Coffee cup", "(C)" "(c)"
+"phone" = "Telephone receiver", "(T)" "(t)"
+"beer" = "Beer mug", "(B)" "(b)"
+"drink" = "Martini glass", "(D)" "(d)"
+"male" = "Boy", "(Z)" "(z)"
+"female" = "Girl", "(X)" "(x)"
+"yes" = "Thumbs up", "(Y)" "(y)"
+"no" = "Thumbs down", "(N)" "(n)"
+"vampire" = "", ":[" ":-["
+"goat" = "Goat", "(nah)"
+"turtle" = "Turtle", "(tu)"
+"plate" = "Plate", "(pl)"
+"bowl" = "Bowl", "(||)"
+"pizza" = "Pizza", "(pi)"
+"soccerball" = "Soccer ball", "(so)"
+"car" = "Auto", "(au)"
+"airplane" = "Airplane", "(ap)"
+"umbrella" = "Umbrella", "(um)"
+"island" = "Island with a palm tree", "(ip)"
+"computer" = "Computer", "(co)"
+"mobile" = "Mobile phone", "(mp)"
+"brb" = "Be right back", "(brb)"
+"rain" = "Storm cloud", "(st)"
+"highfive" = "Hi five!", "(h5)"
+"coins" = "Money", "(mo)"
+"dont-know" = "", ":^)"
+"thunder" = "", "(li)"
+"console" = "XBox", "(xx)"
+"cigarette" = "Cigar", "(ci)"
+"handcuffs" = "Handcuffs", "(%)"
+"fingers-crossed" = "Cross Fingers", "(yn)"
+"immakingadifference" = "i'm™ initiative", "*red+u" "*bgca" "*naf" "*hsus" "*9mil" "*mssoc" "*sierra" "*unicef" "*help" "*komen"
+"bunny" = "Bunny", "('.')" \ No newline at end of file
diff --git a/Plugins/emoticons/data/Plugins/Emoticons/YAHOO.emo b/Plugins/emoticons/data/Plugins/Emoticons/YAHOO.emo
new file mode 100644
index 0000000..bb73674
--- /dev/null
+++ b/Plugins/emoticons/data/Plugins/Emoticons/YAHOO.emo
@@ -0,0 +1,89 @@
+# Yahoo protocol emoticons
+
+"smile" = "Happy", ":)" ":-)"
+"sad" = "Sad", ":(" ":-("
+"wink" = "Winking", ";)" ";-)"
+"smile-big" = "Big grin", ":D" ":-D" ":d" ":-d"
+"lashes" = "Batting eyelashes", ";;)" ";;-)"
+"hug-left" = "Big hug", ">:D<" ">:d<"
+"question" = "Confused", ":-/" ":-\\"
+"in-love" = "Love struck", ":x" ":-x" ":X" ":-X"
+"embarrassed" = "Blushing", ":\">"
+"tongue" = "Tongue", ":P" ":-P" ":p" ":-p"
+"kiss" = "Kiss", ":-*" ":*"
+"love-over" = "Broken heart", "=(("
+"shock" = "Surprise", ":-O" ":o" ":O" ":-o"
+"angry" = "Angry smile", "X(" "X-(" "x(" "x-("
+"mean" = "Smug", ":>" ":->"
+"glass-cool" = "Cool", "B-)" "b-)"
+"confused" = "Worried", ":-S"
+"sweat" = "Whew!", "#:-S" "#:-s"
+"devilish" = "Devil", ">:)"
+"crying" = "Crying", ":(("
+"laugh" = "Laughing", ":))" ":-))"
+"neutral" = "Straight face", ":|" ":-|"
+"sarcastic" = "Raised eyebrow", "/:)"
+"rotfl" = "Rolling on the floor", "=))"
+"angel" = "Angel", "O:-)" "o:-)" "0:-)"
+"glass-nerdy" = "Nerd", ":-B" ":-b"
+"talktohand" = "Talk to the hand", "=;"
+"call-me" = "Call me", ":-c" ":-C"
+"on-the-phone" = "On the phone", ":)]"
+"desperate" = "At wits' end", "~X("
+"bye" = "Wave", ":-h"
+"time-out" = "Time out", ":-t"
+"desire" = "Daydreaming", "8->"
+"sleepy" = "Sleepy", "|-)" "I-)" "i-)"
+"eyeroll" = "Rolling eyes", "8-|"
+"loser" = "Loser", "L-)" "l-)"
+"sick" = "Sick", ":-&"
+"quiet" = "Don't tell anyone", ":-$"
+"arrogant" = "Not talking", "[-("
+"clown" = "Clown", ":O)" ":o)"
+"silly" = "Silly", "8-}"
+"party" = "Party", "<:-P" "<:-p"
+"yawn" = "Yawn", "(:|"
+"drool" = "Drooling", "=P~" "=p~"
+"thinking" = "Thinking", ":-?"
+"doh" = "D'oh", "#-o" "#-O"
+"clap" = "Applause", "=D>" "=d>"
+"nailbiting" = "Nailbiting", ":-SS" ":-Ss" ":-sS" ":-ss"
+"hypnotized" = "Hypnotized", "@-)"
+"lying" = "Liar", ":^o" ":^O"
+"waiting" = "Waiting", ":-w" ":-W"
+"weep" = "Sigh", ":-<"
+"mad-tongue" = "phbbbbt", ">:P" ">:p"
+"cowboy" = "Cowboy", "<):)"
+"dog" = "Puppy dog eyes", ":o3" ":O3"
+"dont-know" = "I don't know", ":-??"
+"not-listening" = "Not listening", "%-("
+"pig" = "Pig", ":@)"
+"cow" = "Cow", "3:-O" "3:-o"
+"monkey" = "Monkey", ":(|)"
+"chicken" = "Chicken", "~:>"
+"rose" = "Rose", "@};-"
+"clover" = "Good luck", "%%-"
+"usa" = "Flag", "**=="
+"pumpkin" = "Pumpkin", "(~~)"
+"coffee" = "Coffee", "~O)" "~o)"
+"lamp" = "Idea", "*-:)"
+"skeleton" = "Skull", "8-X" "8-x"
+"bug" = "Bug", "=:)"
+"alien" = "Alien", ">-)"
+"disapointed" = "Frustrated", ":-L" ":-l"
+"pray" = "Praying", "[-O<" "[-o<"
+"coins" = "Money eyes", "$-)"
+"music" = "Whistling", ":-\""
+"beat-up" = "Feeling beat up", "b-(" "B-("
+"peace" = "Peace sign", ":)>-"
+"shame-on-you" = "Shame on you", "[-X"
+"dance" = "Dancing", "\:D/" "\:d/"
+"pick-fight" = "Bring it on", ">:/"
+"giggle" = "Hee hee", ";))"
+"boring" = "Chatterbox", ":-@"
+"worship" = "Not worthy", "^:)^"
+"oh-go-on" = "Oh go on", ":-j" ":-J"
+"star" = "Star", "(*)"
+"male" = "Hiro / Billy", "o->" "o=>"
+"female" = "April", "o-+"
+"yin-yang" = "Yin yang", "(%)"
diff --git a/Plugins/emoticons/data/Plugins/Emoticons/downloading.gif b/Plugins/emoticons/data/Plugins/Emoticons/downloading.gif
new file mode 100644
index 0000000..a34a48d
--- /dev/null
+++ b/Plugins/emoticons/data/Plugins/Emoticons/downloading.gif
Binary files differ
diff --git a/Plugins/emoticons/emoticons.cpp b/Plugins/emoticons/emoticons.cpp
new file mode 100644
index 0000000..ae0ff90
--- /dev/null
+++ b/Plugins/emoticons/emoticons.cpp
@@ -0,0 +1,2172 @@
+/*
+Copyright (C) 2008 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+#include "commons.h"
+
+
+// Prototypes ///////////////////////////////////////////////////////////////////////////
+
+
+PLUGININFOEX pluginInfo={
+ sizeof(PLUGININFOEX),
+#ifdef UNICODE
+ "Emoticons (Unicode)",
+#else
+ "Emoticons",
+#endif
+ PLUGIN_MAKE_VERSION(0,0,1,0),
+ "Emoticons",
+ "Ricardo Pescuma Domenecci",
+ "",
+ "© 2008 Ricardo Pescuma Domenecci",
+ "http://pescuma.org/miranda/emoticons",
+ UNICODE_AWARE,
+ 0, //doesn't replace anything built-in
+#ifdef UNICODE
+ { 0x80ad2967, 0x2f29, 0x4550, { 0x87, 0x19, 0x23, 0x26, 0x41, 0xd4, 0xc8, 0x83 } } // {80AD2967-2F29-4550-8719-232641D4C883}
+#else
+ { 0x8b47942a, 0xa294, 0x4b25, { 0x95, 0x1a, 0x20, 0x80, 0x44, 0xc9, 0x4f, 0x4d } } // {8B47942A-A294-4b25-951A-208044C94F4D}
+#endif
+};
+
+
+HINSTANCE hInst;
+PLUGINLINK *pluginLink;
+
+HANDLE hHooks[3] = {0};
+HANDLE hServices[3] = {0};
+
+HANDLE hProtocolsFolder = NULL;
+TCHAR protocolsFolder[1024];
+
+HANDLE hEmoticonPacksFolder = NULL;
+TCHAR emoticonPacksFolder[1024];
+
+char *metacontacts_proto = NULL;
+BOOL has_anismiley = FALSE;
+BOOL loaded = FALSE;
+
+typedef map<HWND, Dialog *> DialogMapType;
+
+DialogMapType dialogData;
+
+LIST_INTERFACE li;
+FI_INTERFACE *fei = NULL;
+
+LIST<Module> modules(10);
+LIST<EmoticonPack> packs(10);
+LIST<Contact> contacts(10);
+LIST<OleImage> downloading(10);
+
+BOOL LoadModule(Module *m);
+void LoadModules();
+BOOL LoadPack(EmoticonPack *p);
+void LoadPacks();
+
+void FillModuleImages(EmoticonPack *pack);
+
+EmoticonPack *GetPack(char *name);
+Module *GetModule(const char *name);
+Contact * GetContact(HANDLE hContact);
+CustomEmoticon *GetCustomEmoticon(Contact *c, TCHAR *text);
+EmoticonImage * GetModuleImage(EmoticonImage *img, Module *m);
+void ReleaseModuleImage(EmoticonImage *img);
+
+int ModulesLoaded(WPARAM wParam, LPARAM lParam);
+int PreShutdown(WPARAM wParam, LPARAM lParam);
+int MsgWindowEvent(WPARAM wParam, LPARAM lParam);
+int CustomSmileyReceivedEvent(WPARAM wParam, LPARAM lParam);
+
+int ReplaceEmoticonsService(WPARAM wParam, LPARAM lParam);
+int GetInfo2Service(WPARAM wParam, LPARAM lParam);
+int ShowSelectionService(WPARAM wParam, LPARAM lParam);
+
+TCHAR *GetText(RichEditCtrl &rec, int start, int end);
+
+
+LRESULT CALLBACK MenuWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+
+#define DEFINE_GUIDXXX(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
+ const GUID CDECL name \
+ = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
+
+DEFINE_GUIDXXX(IID_ITextDocument,0x8CC497C0,0xA1DF,0x11CE,0x80,0x98,
+ 0x00,0xAA,0x00,0x47,0xBE,0x5D);
+
+#define SUSPEND_UNDO(rec) \
+ if (rec.textDocument != NULL) \
+ rec.textDocument->Undo(tomSuspend, NULL)
+
+#define RESUME_UNDO(rec) \
+ if (rec.textDocument != NULL) \
+ rec.textDocument->Undo(tomResume, NULL)
+
+#define STOP_RICHEDIT(rec) \
+ SUSPEND_UNDO(rec); \
+ SendMessage(rec.hwnd, WM_SETREDRAW, FALSE, 0); \
+ POINT __old_scroll_pos; \
+ SendMessage(rec.hwnd, EM_GETSCROLLPOS, 0, (LPARAM) &__old_scroll_pos); \
+ CHARRANGE __old_sel; \
+ SendMessage(rec.hwnd, EM_EXGETSEL, 0, (LPARAM) &__old_sel); \
+ POINT __caretPos; \
+ GetCaretPos(&__caretPos); \
+ DWORD __old_mask = SendMessage(rec.hwnd, EM_GETEVENTMASK, 0, 0); \
+ SendMessage(rec.hwnd, EM_SETEVENTMASK, 0, __old_mask & ~ENM_CHANGE); \
+ BOOL __inverse = (__old_sel.cpMin >= LOWORD(SendMessage(rec.hwnd, EM_CHARFROMPOS, 0, (LPARAM) &__caretPos)))
+
+#define START_RICHEDIT(rec) \
+ if (__inverse) \
+ { \
+ LONG __tmp = __old_sel.cpMin; \
+ __old_sel.cpMin = __old_sel.cpMax; \
+ __old_sel.cpMax = __tmp; \
+ } \
+ SendMessage(rec.hwnd, EM_SETEVENTMASK, 0, __old_mask); \
+ SendMessage(rec.hwnd, EM_EXSETSEL, 0, (LPARAM) &__old_sel); \
+ SendMessage(rec.hwnd, EM_SETSCROLLPOS, 0, (LPARAM) &__old_scroll_pos); \
+ SendMessage(rec.hwnd, WM_SETREDRAW, TRUE, 0); \
+ InvalidateRect(rec.hwnd, NULL, FALSE); \
+ RESUME_UNDO(rec)
+
+
+// Functions ////////////////////////////////////////////////////////////////////////////
+
+
+extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
+{
+ hInst = hinstDLL;
+ return TRUE;
+}
+
+
+extern "C" __declspec(dllexport) PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{
+ pluginInfo.cbSize = sizeof(PLUGININFO);
+ return (PLUGININFO*) &pluginInfo;
+}
+
+
+extern "C" __declspec(dllexport) PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ pluginInfo.cbSize = sizeof(PLUGININFOEX);
+ return &pluginInfo;
+}
+
+
+static const MUUID interfaces[] = { MIID_SMILEY, MIID_LAST };
+extern "C" __declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+
+extern "C" int __declspec(dllexport) Load(PLUGINLINK *link)
+{
+ pluginLink = link;
+
+ // TODO Assert results here
+ init_mir_malloc();
+ mir_getLI(&li);
+ CallService(MS_IMG_GETINTERFACE, FI_IF_VERSION, (LPARAM) &fei);
+
+ // hooks
+ hHooks[0] = HookEvent(ME_SYSTEM_MODULESLOADED, ModulesLoaded);
+ hHooks[1] = HookEvent(ME_SYSTEM_PRESHUTDOWN, PreShutdown);
+
+ return 0;
+}
+
+
+extern "C" int __declspec(dllexport) Unload(void)
+{
+ return 0;
+}
+
+
+// Called when all the modules are loaded
+int ModulesLoaded(WPARAM wParam, LPARAM lParam)
+{
+ if (ServiceExists(MS_MC_GETPROTOCOLNAME))
+ metacontacts_proto = (char *) CallService(MS_MC_GETPROTOCOLNAME, 0, 0);
+
+ has_anismiley = ServiceExists(MS_INSERTANISMILEY);
+
+ // add our modules to the KnownModules list
+ CallService("DBEditorpp/RegisterSingleModule", (WPARAM) MODULE_NAME, 0);
+
+ TCHAR mirandaFolder[1024];
+ GetModuleFileName(GetModuleHandle(NULL), mirandaFolder, MAX_REGS(mirandaFolder));
+ TCHAR *p = _tcsrchr(mirandaFolder, _T('\\'));
+ if (p != NULL)
+ *p = _T('\0');
+
+ // updater plugin support
+ if(ServiceExists(MS_UPDATE_REGISTER))
+ {
+ Update upd = {0};
+ char szCurrentVersion[30];
+
+ upd.cbSize = sizeof(upd);
+ upd.szComponentName = pluginInfo.shortName;
+
+ upd.szUpdateURL = UPDATER_AUTOREGISTER;
+
+ upd.szBetaVersionURL = "http://pescuma.org/miranda/emoticons_version.txt";
+ upd.szBetaChangelogURL = "http://pescuma.org/miranda/emoticons#Changelog";
+ upd.pbBetaVersionPrefix = (BYTE *)"Emoticons ";
+ upd.cpbBetaVersionPrefix = strlen((char *)upd.pbBetaVersionPrefix);
+#ifdef UNICODE
+ upd.szBetaUpdateURL = "http://pescuma.org/miranda/emoticonsW.zip";
+#else
+ upd.szBetaUpdateURL = "http://pescuma.org/miranda/emoticons.zip";
+#endif
+
+ upd.pbVersion = (BYTE *)CreateVersionStringPlugin((PLUGININFO*) &pluginInfo, szCurrentVersion);
+ upd.cpbVersion = strlen((char *)upd.pbVersion);
+
+ CallService(MS_UPDATE_REGISTER, 0, (LPARAM)&upd);
+ }
+
+ // Folders plugin support
+ if (ServiceExists(MS_FOLDERS_REGISTER_PATH))
+ {
+ hProtocolsFolder = (HANDLE) FoldersRegisterCustomPathT(Translate("Emoticons"),
+ Translate("Protocols Configuration"),
+ _T(MIRANDA_PATH) _T("\\Plugins\\Emoticons"));
+
+ FoldersGetCustomPathT(hProtocolsFolder, protocolsFolder, MAX_REGS(protocolsFolder), _T("."));
+
+ hEmoticonPacksFolder = (HANDLE) FoldersRegisterCustomPathT(Translate("Emoticons"),
+ Translate("Emoticon Packs"),
+ _T(MIRANDA_PATH) _T("\\Customize\\Emoticons"));
+
+ FoldersGetCustomPathT(hEmoticonPacksFolder, emoticonPacksFolder, MAX_REGS(emoticonPacksFolder), _T("."));
+ }
+ else
+ {
+ mir_sntprintf(protocolsFolder, MAX_REGS(protocolsFolder), _T("%s\\Plugins\\Emoticons"), mirandaFolder);
+ mir_sntprintf(emoticonPacksFolder, MAX_REGS(emoticonPacksFolder), _T("%s\\Customize\\Emoticons"), mirandaFolder);
+ }
+
+ InitOptions();
+
+ LoadModules();
+ LoadPacks();
+
+ if (packs.getCount() > 0)
+ {
+ // Get default pack
+ EmoticonPack *pack = GetPack(opts.pack);
+ if (pack == NULL)
+ pack = packs[0];
+ FillModuleImages(pack);
+ }
+
+
+ hHooks[2] = HookEvent(ME_MSG_WINDOWEVENT, &MsgWindowEvent);
+
+ hServices[0] = CreateServiceFunction(MS_SMILEYADD_REPLACESMILEYS, ReplaceEmoticonsService);
+ hServices[1] = CreateServiceFunction(MS_SMILEYADD_GETINFO2, GetInfo2Service);
+ hServices[2] = CreateServiceFunction(MS_SMILEYADD_SHOWSELECTION, ShowSelectionService);
+
+ // Hook custom emoticons notification
+ PROTOCOLDESCRIPTOR **protos;
+ int count;
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&count, (LPARAM)&protos);
+ for (int i = 0; i < count; i++)
+ {
+ if (protos[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+
+ if (protos[i]->szName == NULL || protos[i]->szName[0] == '\0')
+ continue;
+
+ char evname[250];
+ mir_snprintf(evname, MAX_REGS(evname), "%s%s", protos[i]->szName, ME_CUSTOMSMILEY_RECEIVED);
+ HookEvent(evname, &CustomSmileyReceivedEvent);
+ }
+
+ loaded = TRUE;
+
+ return 0;
+}
+
+
+int PreShutdown(WPARAM wParam, LPARAM lParam)
+{
+ int i;
+
+ for(i = downloading.getCount() - 1; i >= 0; i--)
+ {
+ OleImage *oimg = downloading[i];
+ oimg->Release();
+
+ downloading.remove(i);
+ }
+
+ // Delete packs
+ for(i = 0; i < packs.getCount(); i++)
+ {
+ delete packs[i];
+ }
+ packs.destroy();
+
+ // Delete modules
+ for(i = 0; i < modules.getCount(); i++)
+ {
+ delete modules[i];
+ }
+ modules.destroy();
+
+ for(i = 0; i < MAX_REGS(hServices); i++)
+ DestroyServiceFunction(hServices[i]);
+
+ for(i = 0; i < MAX_REGS(hHooks); i++)
+ UnhookEvent(hHooks[i]);
+
+ DeInitOptions();
+
+ return 0;
+}
+
+
+// Return the size difference with the original text
+int ReplaceEmoticonBackwards(RichEditCtrl &rec, Contact *contact, Module *module, TCHAR *text, int text_len, int last_pos, TCHAR next_char)
+{
+ // This are needed to allow 2 different emoticons that end the same way
+ char found_path[1024];
+ int found_len = -1;
+ TCHAR *found_text;
+ BOOL down = FALSE;
+
+ // Replace normal emoticons
+ if (!opts.only_replace_isolated || next_char == _T('\0') || _istspace(next_char))
+ {
+ for(int i = 0; i < module->emoticons.getCount(); i++)
+ {
+ Emoticon *e = module->emoticons[i];
+ if (e->img == NULL)
+ continue;
+
+ for(int j = 0; j < e->texts.getCount(); j++)
+ {
+ TCHAR *txt = e->texts[j];
+ int len = lstrlen(txt);
+ if (last_pos < len || text_len < len)
+ continue;
+
+ if (len <= found_len)
+ continue;
+
+ if (_tcsncmp(&text[text_len - len], txt, len) != 0)
+ continue;
+
+ if (opts.only_replace_isolated && text_len > len
+ && !_istspace(text[text_len - len - 1]))
+ continue;
+
+ mir_snprintf(found_path, MAX_REGS(found_path), "%s\\%s", e->img->pack->path, e->img->relPath);
+ found_len = len;
+ found_text = txt;
+ }
+ }
+ }
+
+ // Replace custom smileys
+ if (contact != NULL)
+ {
+ for(int i = 0; i < contact->emoticons.getCount(); i++)
+ {
+ CustomEmoticon *e = contact->emoticons[i];
+
+ TCHAR *txt = e->text;
+ int len = lstrlen(txt);
+ if (last_pos < len || text_len < len)
+ continue;
+
+ if (len <= found_len)
+ continue;
+
+ if (_tcsncmp(&text[text_len - len], txt, len) != 0)
+ continue;
+
+ mir_snprintf(found_path, MAX_REGS(found_path), "%s", e->path);
+ found_len = len;
+ found_text = txt;
+ down = e->downloading;
+ }
+ }
+
+ int ret = 0;
+
+ if (found_len > 0)
+ {
+ // Found ya
+ CHARRANGE sel = { last_pos - found_len, last_pos };
+ SendMessage(rec.hwnd, EM_EXSETSEL, 0, (LPARAM) &sel);
+
+ if (has_anismiley)
+ {
+ CHARFORMAT2 cf;
+ memset(&cf, 0, sizeof(CHARFORMAT2));
+ cf.cbSize = sizeof(CHARFORMAT2);
+ cf.dwMask = CFM_BACKCOLOR;
+ SendMessage(rec.hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf);
+
+ if (cf.dwEffects & CFE_AUTOBACKCOLOR)
+ {
+ cf.crBackColor = SendMessage(rec.hwnd, EM_SETBKGNDCOLOR, 0, GetSysColor(COLOR_WINDOW));
+ SendMessage(rec.hwnd, EM_SETBKGNDCOLOR, 0, cf.crBackColor);
+ }
+
+ TCHAR *path = mir_a2t(found_path);
+ if (InsertAnimatedSmiley(rec.hwnd, path, cf.crBackColor, 0 , found_text))
+ {
+ ret = - found_len + 1;
+ }
+ MIR_FREE(path);
+ }
+ else
+ {
+ OleImage *img = new OleImage(found_path, found_text, found_text);
+ if (!img->isValid())
+ {
+ if (down && img->ShowDownloadingIcon(TRUE))
+ {
+ img->AddRef();
+ downloading.insert(img);
+ }
+ else
+ {
+ delete img;
+ return 0;
+ }
+ }
+
+ IOleClientSite *clientSite;
+ rec.ole->GetClientSite(&clientSite);
+
+ REOBJECT reobject = {0};
+ reobject.cbStruct = sizeof(REOBJECT);
+ reobject.cp = REO_CP_SELECTION;
+ reobject.dvaspect = DVASPECT_CONTENT;
+ reobject.poleobj = img;
+ reobject.polesite = clientSite;
+ reobject.dwFlags = REO_BELOWBASELINE; // | REO_DYNAMICSIZE;
+
+ if (rec.ole->InsertObject(&reobject) == S_OK)
+ {
+ img->SetClientSite(clientSite);
+ ret = - found_len + 1;
+ }
+
+ clientSite->Release();
+ img->Release();
+ }
+ }
+
+ return ret;
+}
+
+void FixSelection(LONG &sel, LONG end, int dif)
+{
+ if (sel >= end)
+ sel += dif;
+ else if (sel >= min(end, end + dif))
+ sel = min(end, end + dif);
+}
+
+
+TCHAR *GetText(RichEditCtrl &rec, int start, int end)
+{
+ if (end <= start)
+ end = GetWindowTextLength(rec.hwnd);
+
+ ITextRange *range;
+ if (rec.textDocument->Range(start, end, &range) != S_OK)
+ return FALSE;
+
+ BSTR text = NULL;
+ if (range->GetText(&text) != S_OK || text == NULL)
+ {
+ range->Release();
+ return _T("");
+ }
+
+ TCHAR *ret = mir_u2t(text);
+
+ SysFreeString(text);
+
+ range->Release();
+
+ return ret;
+/*
+ CHARRANGE sel = { start, end };
+ if (sel.cpMax <= sel.cpMin)
+ sel.cpMax = GetWindowTextLength(hwnd);
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM) &sel);
+ SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM) &sel);
+
+ int len = sel.cpMax - sel.cpMin;
+ TCHAR *text = (TCHAR *) malloc((len + 1) * sizeof(TCHAR));
+
+ GETTEXTEX ste = {0};
+ ste.cb = (len + 1) * sizeof(TCHAR);
+ ste.flags = ST_SELECTION;
+#ifdef UNICODE
+ ste.codepage = 1200; // UNICODE
+ SendMessage(hwnd, EM_GETTEXTEX, (WPARAM) &ste, (LPARAM) text);
+#else
+ ste.codepage = CP_ACP;
+ SendMessage(hwnd, EM_GETTEXTEX, (WPARAM) &ste, (LPARAM) text);
+#endif
+
+ return text;
+*/
+}
+
+
+BOOL IsHidden(RichEditCtrl &rec, int start, int end)
+{
+ ITextRange *range;
+ if (rec.textDocument->Range(start, end, &range) != S_OK)
+ return FALSE;
+
+ ITextFont *font;
+ if (range->GetFont(&font) != S_OK)
+ {
+ range->Release();
+ return FALSE;
+ }
+
+ long hidden;
+ font->GetHidden(&hidden);
+ BOOL ret = (hidden == tomTrue);
+
+ font->Release();
+ range->Release();
+
+ return ret;
+
+/* CHARRANGE sel = { start, end };
+ SendMessage(hwnd, EM_EXSETSEL, 0, (LPARAM) &sel);
+ SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM) &sel);
+
+ CHARFORMAT2 cf;
+ memset(&cf, 0, sizeof(CHARFORMAT2));
+ cf.cbSize = sizeof(CHARFORMAT2);
+ cf.dwMask = CFM_HIDDEN;
+ SendMessageA(hwnd, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf);
+ return (cf.dwEffects & CFE_HIDDEN) != 0;
+*/
+}
+
+
+void ReplaceAllEmoticonsBackwards(RichEditCtrl &rec, Contact *contact, Module *module, TCHAR *text, int len, TCHAR next_char, int start, CHARRANGE &__old_sel)
+{
+ for(int i = len; i > 0; i--)
+ {
+ int dif = ReplaceEmoticonBackwards(rec, contact, module, text, i, start + i, i == len ? next_char : text[i]);
+ if (dif != 0)
+ {
+ FixSelection(__old_sel.cpMax, i, dif);
+ FixSelection(__old_sel.cpMin, i, dif);
+
+ i += dif;
+ }
+ }
+}
+
+
+void ReplaceAllEmoticonsBackwards(RichEditCtrl &rec, Contact *contact, Module *module)
+{
+ STOP_RICHEDIT(rec);
+
+ TCHAR *text = GetText(rec, 0, -1);
+ int len = lstrlen(text);
+
+ ReplaceAllEmoticonsBackwards(rec, contact, module, text, len, _T('\0'), 0, __old_sel);
+
+ MIR_FREE(text);
+
+ START_RICHEDIT(rec);
+}
+
+
+int matches(const TCHAR *tag, const TCHAR *text)
+{
+ int len = lstrlen(tag);
+ if (_tcsncmp(tag, text, len) == 0)
+ return len;
+ else
+ return 0;
+}
+
+
+static TCHAR *webs[] = {
+ _T("http://"),
+ _T("ftp://"),
+ _T("irc://"),
+ _T("gopher://"),
+ _T("file://"),
+ _T("www."),
+ _T("www2."),
+ _T("ftp."),
+ _T("irc."),
+ _T("A:\\"),
+ _T("B:\\"),
+ _T("C:\\"),
+ _T("D:\\"),
+};
+
+
+void ReplaceAllEmoticons(RichEditCtrl &rec, Contact *contact, Module *module, int start, int end)
+{
+ STOP_RICHEDIT(rec);
+
+ if (start < 0)
+ start = 0;
+
+ TCHAR *text = GetText(rec, start, end);
+ int len = lstrlen(text);
+
+ int last_start_pos = 0;
+ BOOL replace = TRUE;
+ HANDLE hContact = (contact == NULL ? NULL : contact->hContact);
+ for(int i = 0; i <= len; i++)
+ {
+ int tl;
+ if (replace)
+ {
+ if (i == 0 || !_istalnum(text[i - 1]))
+ {
+ for (int j = 0; j < MAX_REGS(webs); j++)
+ {
+ if (tl = matches(webs[j], &text[i]))
+ {
+ ReplaceAllEmoticonsBackwards(rec, contact, module, &text[last_start_pos], i - last_start_pos, _T('\0'), start + last_start_pos, __old_sel);
+
+ i += tl;
+
+ for(; (text[i] >= _T('a') && text[i] <= _T('z'))
+ || (text[i] >= _T('A') && text[i] <= _T('Z'))
+ || (text[i] >= _T('0') && text[i] <= _T('9'))
+ || text[i] == _T('.') || text[i] == _T('/')
+ || text[i] == _T('?') || text[i] == _T('_')
+ || text[i] == _T('=') || text[i] == _T('&')
+ || text[i] == _T('%') || text[i] == _T('-')
+ ; i++) ;
+
+ last_start_pos = i;
+ }
+ }
+ }
+ }
+
+ if (tl = matches(_T("<no-emoticon>"), &text[i]))
+ {
+ if (IsHidden(rec, start + i, start + i + tl))
+ {
+ ReplaceAllEmoticonsBackwards(rec, contact, module, &text[last_start_pos], i - last_start_pos, _T('\0'), start + last_start_pos, __old_sel);
+
+ replace = FALSE;
+ i += tl - 1;
+ }
+ continue;
+ }
+
+ if (tl = matches(_T("</no-emoticon>"), &text[i]))
+ {
+ if (IsHidden(rec, start + i, start + i + tl))
+ {
+ replace = TRUE;
+ i += tl - 1;
+ last_start_pos = i + 1;
+ }
+ continue;
+ }
+
+ if (tl = matches(_T("</emoticon-contact>"), &text[i]))
+ {
+ if (IsHidden(rec, start + i, start + i + tl))
+ {
+ ReplaceAllEmoticonsBackwards(rec, contact, module, &text[last_start_pos], i - last_start_pos, _T('\0'), start + last_start_pos, __old_sel);
+
+ hContact = (contact == NULL ? NULL : contact->hContact);
+ i += tl - 1;
+ last_start_pos = i + 1;
+ }
+ continue;
+ }
+
+ if (tl = matches(_T("<emoticon-contact "), &text[i]))
+ {
+ int len = tl;
+ for(int j = 0; j < 10 && text[i + len] != '>'; j++, len++)
+ ;
+
+ if (text[i + len] != '>')
+ continue;
+
+ len++;
+
+ if (IsHidden(rec, start + i, start + i + len))
+ {
+ ReplaceAllEmoticonsBackwards(rec, contact, module, &text[last_start_pos], i - last_start_pos, _T('\0'), start + last_start_pos, __old_sel);
+
+ hContact = (HANDLE) _ttoi(&text[i + tl]);
+ i += len - 1;
+ last_start_pos = i + 1;
+ }
+ }
+ }
+
+ if (replace)
+ ReplaceAllEmoticonsBackwards(rec, contact, module, &text[last_start_pos], len - last_start_pos, _T('\0'), start + last_start_pos, __old_sel);
+
+ MIR_FREE(text);
+
+ START_RICHEDIT(rec);
+}
+
+
+int RestoreInput(RichEditCtrl &rec, int start = 0, int end = -1)
+{
+ int ret = 0;
+
+ int objectCount = rec.ole->GetObjectCount();
+ for (int i = objectCount - 1; i >= 0; i--)
+ {
+ REOBJECT reObj = {0};
+ reObj.cbStruct = sizeof(REOBJECT);
+
+ HRESULT hr = rec.ole->GetObject(i, &reObj, REO_GETOBJ_POLEOBJ);
+ if (!SUCCEEDED(hr))
+ continue;
+
+ if (reObj.cp < start || (end >= start && reObj.cp >= end))
+ {
+ reObj.poleobj->Release();
+ continue;
+ }
+
+ ITooltipData *ttd = NULL;
+ hr = reObj.poleobj->QueryInterface(__uuidof(ITooltipData), (void**) &ttd);
+ reObj.poleobj->Release();
+ if (SUCCEEDED(hr) && ttd == NULL)
+ continue;
+
+ BSTR hint = NULL;
+ hr = ttd->GetTooltip(&hint);
+ if (SUCCEEDED(hr) && hint != NULL)
+ {
+ ITextRange *range;
+ if (rec.textDocument->Range(reObj.cp, reObj.cp + 1, &range) == S_OK)
+ {
+ if (range->SetText(hint) == S_OK)
+ ret += wcslen(hint) - 1;
+
+ range->Release();
+ }
+
+ SysFreeString(hint);
+ }
+
+ ttd->Release();
+ }
+
+ return ret;
+}
+
+
+LRESULT CALLBACK EditProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ DialogMapType::iterator dlgit = dialogData.find(hwnd);
+ if (dlgit == dialogData.end())
+ return -1;
+
+ Dialog *dlg = dlgit->second;
+
+ LRESULT ret = CallWindowProc(dlg->input.old_edit_proc, hwnd, msg, wParam, lParam);
+
+ switch(msg)
+ {
+ case WM_KEYDOWN:
+ {
+ if (wParam != VK_DELETE && wParam != VK_BACK)
+ break;
+ }
+ case WM_CHAR:
+ {
+ if (msg == WM_CHAR && wParam >= 0 && wParam <= 32 && (!_istspace(wParam) || !opts.only_replace_isolated))
+ break;
+
+ if (lParam & (1 << 28)) // ALT key
+ break;
+
+ if (wParam != _T('\n') && GetKeyState(VK_CONTROL) & 0x8000) // CTRL key
+ break;
+
+ if ((lParam & 0xFF) > 2) // Repeat rate
+ break;
+
+ STOP_RICHEDIT(dlg->input);
+
+ CHARRANGE sel = {0};
+ SendMessage(hwnd, EM_EXGETSEL, 0, (LPARAM) &sel);
+
+ int min = max(0, sel.cpMax - 10);
+
+ int dif = RestoreInput(dlg->input, min, sel.cpMax);
+ if (dif != 0)
+ {
+ FixSelection(__old_sel.cpMax, sel.cpMax, dif);
+ FixSelection(__old_sel.cpMin, sel.cpMax, dif);
+ sel.cpMax += dif;
+ }
+
+ TCHAR *text = GetText(dlg->input, min, sel.cpMax + 1);
+ int len = lstrlen(text);
+ TCHAR last;
+ if (len == sel.cpMax + 1 - min)
+ {
+ // Strip
+ len--;
+ last = text[len];
+ }
+ else
+ {
+ last = _T('\0');
+ }
+
+ if (dif == 0 && !opts.only_replace_isolated)
+ {
+ // Can replace just last text
+ dif = ReplaceEmoticonBackwards(dlg->input, NULL, dlg->module, text, len, sel.cpMax, last);
+ if (dif != 0)
+ {
+ FixSelection(__old_sel.cpMax, sel.cpMax, dif);
+ FixSelection(__old_sel.cpMin, sel.cpMax, dif);
+ }
+ }
+ else
+ {
+ // Because we already changed the text, we need to replace all range
+ ReplaceAllEmoticonsBackwards(dlg->input, NULL, dlg->module, text, len, last, min, __old_sel);
+ }
+
+ MIR_FREE(text);
+
+ START_RICHEDIT(dlg->input);
+
+ break;
+ }
+ case EM_REPLACESEL:
+ case WM_SETTEXT:
+ case EM_SETTEXTEX:
+ if (dlg->log.sending)
+ break;
+ case EM_PASTESPECIAL:
+ case WM_PASTE:
+ {
+ ReplaceAllEmoticonsBackwards(dlg->input, NULL, dlg->module);
+
+ break;
+ }
+ }
+
+ return ret;
+}
+
+/*
+LRESULT CALLBACK LogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ DialogMapType::iterator dlgit = dialogData.find(hwnd);
+ if (dlgit == dialogData.end())
+ return -1;
+
+ Dialog *dlg = dlgit->second;
+
+ switch(msg)
+ {
+ case WM_SETREDRAW:
+ {
+ if (wParam == FALSE)
+ {
+ dlg->log.received_stream_in = FALSE;
+ }
+ else
+ {
+ if (dlg->log.received_stream_in)
+ {
+ RichEditCtrl &rec = dlg->log;
+ SUSPEND_UNDO(rec); \
+ POINT __old_scroll_pos; \
+ SendMessage(rec.hwnd, EM_GETSCROLLPOS, 0, (LPARAM) &__old_scroll_pos); \
+ CHARRANGE __old_sel; \
+ SendMessage(rec.hwnd, EM_EXGETSEL, 0, (LPARAM) &__old_sel); \
+ POINT __caretPos; \
+ GetCaretPos(&__caretPos); \
+ DWORD __old_mask = SendMessage(rec.hwnd, EM_GETEVENTMASK, 0, 0); \
+ SendMessage(rec.hwnd, EM_SETEVENTMASK, 0, __old_mask & ~ENM_CHANGE); \
+ BOOL __inverse = (__old_sel.cpMin >= LOWORD(SendMessage(rec.hwnd, EM_CHARFROMPOS, 0, (LPARAM) &__caretPos)));
+
+ CHARRANGE sel = { dlg->log.stream_in_pos, GetWindowTextLength(dlg->log.hwnd) };
+ SendMessage(dlg->log.hwnd, EM_EXSETSEL, 0, (LPARAM) &sel);
+
+ int len = sel.cpMax - sel.cpMin;
+ TCHAR *text = (TCHAR *) malloc((len + 1) * sizeof(TCHAR));
+ SendMessage(dlg->log.hwnd, EM_GETSELTEXT, 0, (LPARAM) text);
+
+ for(int i = len; i > 0; i--)
+ {
+ int dif = ReplaceEmoticonBackwards(dlg->log.hwnd, text, i, sel.cpMin + i, dlg->module);
+
+ FixSelection(__old_sel.cpMax, i, dif);
+ FixSelection(__old_sel.cpMin, i, dif);
+ }
+
+ if (__inverse) \
+ { \
+ LONG __tmp = __old_sel.cpMin; \
+ __old_sel.cpMin = __old_sel.cpMax; \
+ __old_sel.cpMax = __tmp; \
+ } \
+ SendMessage(rec.hwnd, EM_SETEVENTMASK, 0, __old_mask); \
+ SendMessage(rec.hwnd, EM_EXSETSEL, 0, (LPARAM) &__old_sel); \
+ SendMessage(rec.hwnd, EM_SETSCROLLPOS, 0, (LPARAM) &__old_scroll_pos); \
+ InvalidateRect(rec.hwnd, NULL, FALSE); \
+ RESUME_UNDO(rec);
+ }
+ }
+ break;
+ }
+ case EM_STREAMIN:
+ {
+ dlg->log.received_stream_in = TRUE;
+ dlg->log.stream_in_pos = GetWindowTextLength(dlg->log.hwnd);
+ break;
+ }
+ }
+
+ LRESULT ret = CallWindowProc(dlg->log.old_edit_proc, hwnd, msg, wParam, lParam);
+
+ return ret;
+}
+*/
+
+
+LRESULT CALLBACK OwnerProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ DialogMapType::iterator dlgit = dialogData.find(hwnd);
+ if (dlgit == dialogData.end())
+ return -1;
+
+ Dialog *dlg = dlgit->second;
+
+/* int old_len;
+ if (msg == DM_APPENDTOLOG)
+ {
+ old_len = GetWindowTextLength(dlg->log.hwnd);
+ }
+ else */
+ if (msg == WM_COMMAND && LOWORD(wParam) == IDOK && dlg->input.old_edit_proc != NULL)
+ {
+ dlg->log.sending = TRUE;
+
+ STOP_RICHEDIT(dlg->input);
+
+ RestoreInput(dlg->input);
+
+ START_RICHEDIT(dlg->input);
+ }
+
+ LRESULT ret = CallWindowProc(dlg->owner_old_edit_proc, hwnd, msg, wParam, lParam);
+
+ switch(msg)
+ {
+ case WM_COMMAND:
+ {
+ if (LOWORD(wParam) == IDOK)
+ {
+ if (!ret)
+ // Add emoticons again
+ ReplaceAllEmoticonsBackwards(dlg->input, NULL, dlg->module);
+
+ dlg->log.sending = FALSE;
+ }
+ break;
+ }
+/*
+ case DM_APPENDTOLOG:
+ {
+ break;
+
+ STOP_RICHEDIT(dlg->log);
+
+ TCHAR *text = GetText(dlg->log, old_len, -1);
+ int len = lstrlen(text);
+
+ for(int i = len; i > 0; i--)
+ {
+ int dif = ReplaceEmoticonBackwards(dlg->log.hwnd, text, i, old_len + i, dlg->module);
+
+ FixSelection(__old_sel.cpMax, i, dif);
+ FixSelection(__old_sel.cpMin, i, dif);
+ }
+
+ MIR_FREE(text);
+
+ START_RICHEDIT(dlg->log);
+
+ break;
+ }
+
+ case DM_REMAKELOG:
+ {
+ break;
+
+ STOP_RICHEDIT(dlg->log);
+
+ TCHAR *text = GetText(dlg->log, 0, -1);
+ int len = lstrlen(text);
+
+ for(int i = len; i > 0; i--)
+ {
+ int dif = ReplaceEmoticonBackwards(dlg->log.hwnd, text, i, i, dlg->module);
+
+ FixSelection(__old_sel.cpMax, i, dif);
+ FixSelection(__old_sel.cpMin, i, dif);
+ }
+
+ MIR_FREE(text);
+
+ START_RICHEDIT(dlg->log);
+
+ break;
+ }
+*/
+ }
+
+ return ret;
+}
+
+
+int LoadRichEdit(RichEditCtrl *rec, HWND hwnd)
+{
+ rec->hwnd = hwnd;
+ rec->ole = NULL;
+ rec->textDocument = NULL;
+ rec->old_edit_proc = NULL;
+ rec->received_stream_in = FALSE;
+ rec->sending = FALSE;
+
+ SendMessage(hwnd, EM_GETOLEINTERFACE, 0, (LPARAM)&rec->ole);
+ if (rec->ole == NULL)
+ return 0;
+
+ if (rec->ole->QueryInterface(IID_ITextDocument, (void**)&rec->textDocument) != S_OK)
+ rec->textDocument = NULL;
+
+ return 1;
+}
+
+
+void UnloadRichEdit(RichEditCtrl *rec)
+{
+ if (rec->textDocument != NULL)
+ rec->textDocument->Release();
+ if (rec->ole != NULL)
+ rec->ole->Release();
+}
+
+
+HANDLE GetRealContact(HANDLE hContact)
+{
+ if (!ServiceExists(MS_MC_GETMOSTONLINECONTACT))
+ return hContact;
+
+ HANDLE hReal = (HANDLE) CallService(MS_MC_GETMOSTONLINECONTACT, (WPARAM) hContact, 0);
+ if (hReal == NULL)
+ hReal = hContact;
+ return hReal;
+}
+
+
+int MsgWindowEvent(WPARAM wParam, LPARAM lParam)
+{
+ MessageWindowEventData *event = (MessageWindowEventData *)lParam;
+ if (event == NULL)
+ return 0;
+
+ if (event->cbSize < sizeof(MessageWindowEventData))
+ return 0;
+
+ if (event->uType == MSG_WINDOW_EVT_OPEN)
+ {
+ HANDLE hReal = GetRealContact(event->hContact);
+
+ char *proto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hReal, 0);
+ if (proto == NULL)
+ return 0;
+
+ Module *m = GetModule(proto);
+ if (m == NULL)
+ return 0;
+
+ Dialog *dlg = (Dialog *) malloc(sizeof(Dialog));
+ ZeroMemory(dlg, sizeof(Dialog));
+
+ dlg->contact = GetContact(event->hContact);
+ dlg->module = m;
+ dlg->hwnd_owner = event->hwndWindow;
+
+ LoadRichEdit(&dlg->input, event->hwndInput);
+ LoadRichEdit(&dlg->log, event->hwndLog);
+
+ if (opts.replace_in_input)
+ {
+ dlg->input.old_edit_proc = (WNDPROC) SetWindowLong(dlg->input.hwnd, GWL_WNDPROC, (LONG) EditProc);
+ dialogData[dlg->input.hwnd] = dlg;
+ }
+
+ dlg->owner_old_edit_proc = (WNDPROC) SetWindowLong(dlg->hwnd_owner, GWL_WNDPROC, (LONG) OwnerProc);
+ dialogData[dlg->hwnd_owner] = dlg;
+
+// dlg->log.old_edit_proc = (WNDPROC) SetWindowLong(dlg->log.hwnd, GWL_WNDPROC, (LONG) LogProc);
+ dialogData[dlg->log.hwnd] = dlg;
+ }
+ else if (event->uType == MSG_WINDOW_EVT_CLOSING)
+ {
+ DialogMapType::iterator dlgit = dialogData.find(event->hwndWindow);
+ if (dlgit != dialogData.end())
+ {
+ Dialog *dlg = dlgit->second;
+
+ UnloadRichEdit(&dlg->input);
+ UnloadRichEdit(&dlg->log);
+
+ if (dlg->input.old_edit_proc != NULL)
+ SetWindowLong(dlg->input.hwnd, GWL_WNDPROC, (LONG) dlg->input.old_edit_proc);
+ SetWindowLong(dlg->hwnd_owner, GWL_WNDPROC, (LONG) dlg->owner_old_edit_proc);
+
+ free(dlg);
+ }
+
+ dialogData.erase(event->hwndInput);
+ dialogData.erase(event->hwndLog);
+ dialogData.erase(event->hwndWindow);
+ }
+
+ return 0;
+}
+
+
+TCHAR *lstrtrim(TCHAR *str)
+{
+ int len = lstrlen(str);
+
+ int i;
+ for(i = len - 1; i >= 0 && (str[i] == _T(' ') || str[i] == _T('\t')); --i) ;
+ if (i < len - 1)
+ {
+ ++i;
+ str[i] = _T('\0');
+ len = i;
+ }
+
+ for(i = 0; i < len && (str[i] == _T(' ') || str[i] == _T('\t')); ++i) ;
+ if (i > 0)
+ memmove(str, &str[i], (len - i + 1) * sizeof(TCHAR));
+
+ return str;
+}
+
+
+char *strtrim(char *str)
+{
+ int len = strlen(str);
+
+ int i;
+ for(i = len - 1; i >= 0 && (str[i] == ' ' || str[i] == '\t'); --i) ;
+ if (i < len - 1)
+ {
+ ++i;
+ str[i] = '\0';
+ len = i;
+ }
+
+ for(i = 0; i < len && (str[i] == ' ' || str[i] == '\t'); ++i) ;
+ if (i > 0)
+ memmove(str, &str[i], (len - i + 1) * sizeof(char));
+
+ return str;
+}
+
+
+void LoadModules()
+{
+ // Load the language files and create an array with then
+ TCHAR file[1024];
+ mir_sntprintf(file, MAX_REGS(file), _T("%s\\*.emo"), protocolsFolder);
+
+ WIN32_FIND_DATA ffd = {0};
+ HANDLE hFFD = FindFirstFile(file, &ffd);
+ if (hFFD != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ mir_sntprintf(file, MAX_REGS(file), _T("%s\\%s"), protocolsFolder, ffd.cFileName);
+
+ DWORD attrib = GetFileAttributes(file);
+ if (attrib == 0xFFFFFFFF || (attrib & FILE_ATTRIBUTE_DIRECTORY))
+ continue;
+
+ Module *m = new Module();
+ m->name = mir_t2a(ffd.cFileName);
+ m->name[strlen(m->name) - 4] = 0;
+ m->path = mir_tstrdup(file);
+ modules.insert(m);
+
+ LoadModule(m);
+ }
+ while(FindNextFile(hFFD, &ffd));
+
+ FindClose(hFFD);
+ }
+}
+
+void HandleEmoLine(Module *m, char *tmp)
+{
+ int len = strlen(tmp);
+ int state = 0;
+ int pos;
+
+ Emoticon *e = NULL;
+
+ for(int i = 0; i < len; i++)
+ {
+ char c = tmp[i];
+ if (c == ' ')
+ continue;
+
+ if ((state % 2) == 0)
+ {
+ if (c == '#')
+ break;
+
+ if (c != '"')
+ continue;
+
+ state ++;
+ pos = i+1;
+ }
+ else
+ {
+ if (c == '\\')
+ {
+ i++;
+ continue;
+ }
+ if (c != '"')
+ continue;
+
+ tmp[i] = 0;
+ TCHAR * txt = mir_a2t(&tmp[pos]);
+
+ for(int j = 0, orig = 0; j <= i - pos; j++)
+ {
+ if (txt[j] == '\\')
+ j++;
+ txt[orig] = txt[j];
+ orig++;
+ }
+
+ // Found something
+ switch(state)
+ {
+ case 1:
+ e = new Emoticon();
+ e->name = mir_t2a(txt);
+ MIR_FREE(txt);
+ break;
+ case 3:
+ e->description = txt;
+ break;
+ case 5:
+ e->texts.insert(txt);
+ break;
+ }
+
+ state++;
+ if (state == 6)
+ state = 4;
+ }
+ }
+
+ if (e != NULL)
+ m->emoticons.insert(e);
+}
+
+
+BOOL LoadModule(Module *m)
+{
+ FILE *file = _tfopen(m->path, _T("rb"));
+ if (file == NULL)
+ return FALSE;
+
+ char tmp[1024];
+ char c;
+ int pos = 0;
+ do
+ {
+ c = fgetc(file);
+
+ if (c == '\n' || c == '\r' || c == EOF || pos >= MAX_REGS(tmp) - 1)
+ {
+ tmp[pos] = 0;
+ HandleEmoLine(m, tmp);
+ pos = 0;
+ }
+ else
+ {
+ tmp[pos] = c;
+ pos ++;
+ }
+ }
+ while(c != EOF);
+ fclose(file);
+
+ return TRUE;
+}
+
+
+
+void LoadPacks()
+{
+ // Load the language files and create an array with then
+ TCHAR file[1024];
+ mir_sntprintf(file, MAX_REGS(file), _T("%s\\*"), emoticonPacksFolder);
+
+ WIN32_FIND_DATA ffd = {0};
+ HANDLE hFFD = FindFirstFile(file, &ffd);
+ if (hFFD != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ if (lstrcmp(ffd.cFileName, _T(".")) == 0 || lstrcmp(ffd.cFileName, _T("..")) == 0)
+ continue;
+
+ mir_sntprintf(file, MAX_REGS(file), _T("%s\\%s"), emoticonPacksFolder, ffd.cFileName);
+
+ DWORD attrib = GetFileAttributes(file);
+ if (attrib == 0xFFFFFFFF || !(attrib & FILE_ATTRIBUTE_DIRECTORY))
+ continue;
+
+ EmoticonPack *p = new EmoticonPack();
+ p->name = mir_t2a(ffd.cFileName);
+ p->description = mir_tstrdup(ffd.cFileName);
+ p->path = mir_t2a(file);
+ packs.insert(p);
+
+ LoadPack(p);
+ }
+ while(FindNextFile(hFFD, &ffd));
+
+ FindClose(hFFD);
+ }
+}
+
+
+EmoticonImage * HandleMepLine(EmoticonPack *p, char *line)
+{
+ int len = strlen(line);
+ int state = 0;
+ int pos;
+ int module_pos = -1;
+
+ EmoticonImage *img = NULL;
+
+ for(int i = 0; i < len && state < 4; i++)
+ {
+ char c = line[i];
+ if (c == ' ')
+ continue;
+
+ if ((state % 2) == 0)
+ {
+ if (c != '"')
+ continue;
+
+ state ++;
+ pos = i+1;
+ }
+ else
+ {
+ if (state == 1 && c == '\\') // Module name
+ module_pos = i;
+
+ if (c != '"')
+ continue;
+
+ line[i] = 0;
+
+ char *module;
+ char *txt;
+
+ if (state == 1 && module_pos >= 0)
+ {
+ line[module_pos] = 0;
+
+ module = mir_strdup(&line[pos]);
+ txt = mir_strdup(&line[module_pos + 1]);
+ }
+ else
+ {
+ module = NULL;
+ txt = mir_strdup(&line[pos]);
+ }
+
+ // Found something
+ switch(state)
+ {
+ case 1:
+ img = new EmoticonImage();
+ img->pack = p;
+ img->name = txt;
+ img->module = module;
+ break;
+ case 3:
+ img->relPath = txt;
+ break;
+ }
+
+ state++;
+ }
+ }
+
+ return img;
+}
+
+
+BOOL LoadPack(EmoticonPack *pack)
+{
+ // Load the language files and create an array with then
+ char filename[1024];
+ mir_snprintf(filename, MAX_REGS(filename), "%s\\*.*", pack->path);
+
+ WIN32_FIND_DATAA ffd = {0};
+ HANDLE hFFD = FindFirstFileA(filename, &ffd);
+ if (hFFD != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ mir_snprintf(filename, MAX_REGS(filename), "%s\\%s", pack->path, ffd.cFileName);
+
+ DWORD attrib = GetFileAttributesA(filename);
+ if (attrib == 0xFFFFFFFF || (attrib & FILE_ATTRIBUTE_DIRECTORY))
+ continue;
+
+ int len = strlen(ffd.cFileName);
+ if (len < 5)
+ continue;
+ if (strcmp(&ffd.cFileName[len-4], ".jpg") != 0
+ && strcmp(&ffd.cFileName[len-4], ".gif") != 0
+ && strcmp(&ffd.cFileName[len-4], ".png"))
+ continue;
+
+ EmoticonImage *img = new EmoticonImage();
+ img->pack = pack;
+ img->name = mir_strdup(ffd.cFileName);
+ img->name[strlen(img->name) - 4] = 0;
+ img->relPath = mir_strdup(ffd.cFileName);
+ pack->images.insert(img);
+ }
+ while(FindNextFileA(hFFD, &ffd));
+
+ FindClose(hFFD);
+ }
+
+ // Load the mep file
+ mir_snprintf(filename, MAX_REGS(filename), "%s\\%s.mep", pack->path, pack->name);
+ FILE *file = fopen(filename, "rb");
+ if (file == NULL)
+ return TRUE;
+
+ char tmp[1024];
+ char c;
+ int pos = 0;
+ do
+ {
+ c = fgetc(file);
+
+ if (c == '\n' || c == '\r' || c == EOF || pos >= MAX_REGS(tmp) - 1)
+ {
+ tmp[pos] = 0;
+
+ strtrim(tmp);
+ if (strnicmp("Name:", tmp, 5) == 0)
+ {
+ char *name = strtrim(&tmp[5]);
+ if (name[0] != '\0')
+ {
+ MIR_FREE(pack->description);
+ pack->description = mir_a2t(name);
+ }
+ }
+ else if (strnicmp("Creator:", tmp, 8) == 0)
+ {
+ char *creator = strtrim(&tmp[8]);
+ if (creator[0] != '\0')
+ pack->creator = mir_a2t(creator);
+ }
+ else if (strnicmp("Updater URL:", tmp, 12) == 0)
+ {
+ char *updater_URL = strtrim(&tmp[12]);
+ if (updater_URL[0] != '\0')
+ pack->updater_URL = mir_a2t(updater_URL);
+ }
+ else if (tmp[0] == '"')
+ {
+ EmoticonImage *img = HandleMepLine(pack, tmp);
+ if (img != NULL)
+ {
+ // Chek if already exists
+ for(int i = 0; i < pack->images.getCount(); i++)
+ {
+ EmoticonImage *tmp_img = pack->images[i];
+ if (strcmp(img->name, tmp_img->name) == 0
+ && ((tmp_img->module == NULL && img->module == NULL)
+ || (tmp_img->module != NULL && img->module != NULL
+ && stricmp(tmp_img->module, img->module) == 0)))
+ {
+ delete tmp_img;
+ pack->images.remove(i);
+ break;
+ }
+ }
+
+ // Add the new one
+ pack->images.insert(img);
+ }
+ }
+
+ pos = 0;
+ }
+ else
+ {
+ tmp[pos] = c;
+ pos ++;
+ }
+ }
+ while(c != EOF);
+ fclose(file);
+
+ return TRUE;
+}
+
+
+EmoticonImage * GetModuleImage(EmoticonPack *pack, EmoticonImage *img, Module *m)
+{
+ if (img->isAvaiableFor(m->name))
+ {
+ EmoticonImage * ret = new EmoticonImage();
+ ret->pack = img->pack;
+ ret->name = mir_strdup(img->name);
+
+ int size = strlen(m->name) + 1 + strlen(img->relPath) + 1;
+ ret->relPath = (char *) mir_alloc(size * sizeof(char));
+ mir_snprintf(ret->relPath, size, "%s\\%s", m->name, img->relPath);
+
+ ret->module = mir_strdup(m->name);
+ pack->images.insert(ret);
+ return ret;
+ }
+ else if (img->isAvaiable())
+ {
+ return img;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+
+EmoticonImage * GetEmoticomImageFromDisk(EmoticonPack *pack, Emoticon *e, Module *module)
+{
+ EmoticonImage *img = NULL;
+
+ char filename[1024];
+ mir_snprintf(filename, MAX_REGS(filename), "%s\\%s\\%s.*", pack->path, module->name, e->name);
+
+ WIN32_FIND_DATAA ffd = {0};
+ HANDLE hFFD = FindFirstFileA(filename, &ffd);
+ if (hFFD != INVALID_HANDLE_VALUE)
+ {
+ do
+ {
+ mir_snprintf(filename, MAX_REGS(filename), "%s\\%s\\%s", pack->path, module->name, ffd.cFileName);
+
+ DWORD attrib = GetFileAttributesA(filename);
+ if (attrib == 0xFFFFFFFF || (attrib & FILE_ATTRIBUTE_DIRECTORY))
+ continue;
+
+ int len = strlen(ffd.cFileName);
+ if (len < 5)
+ continue;
+ if (strcmp(&ffd.cFileName[len-4], ".jpg") != 0
+ && strcmp(&ffd.cFileName[len-4], ".gif") != 0
+ && strcmp(&ffd.cFileName[len-4], ".png"))
+ continue;
+
+ img = new EmoticonImage();
+ img->pack = pack;
+ img->name = mir_strdup(ffd.cFileName);
+ img->name[strlen(img->name) - 4] = 0;
+ img->module = module->name;
+ img->relPath = mir_strdup(ffd.cFileName);
+ break;
+ }
+ while(FindNextFileA(hFFD, &ffd));
+
+ FindClose(hFFD);
+ }
+
+ return img;
+}
+
+
+void FillModuleImages(EmoticonPack *pack)
+{
+ for(int j = 0; j < modules.getCount(); j++)
+ {
+ Module *m = modules[j];
+ for(int k = 0; k < m->emoticons.getCount(); k++)
+ {
+ Emoticon *e = m->emoticons[k];
+
+ // Free old one
+ e->img = NULL;
+
+ // First try from pack file for this module
+ int i;
+ for(i = 0; i < pack->images.getCount(); i++)
+ {
+ EmoticonImage *img = pack->images[i];
+ if (img->module != NULL && stricmp(img->module, m->name) == 0 && strcmp(img->name, e->name) == 0)
+ {
+ e->img = img;
+ break;
+ }
+ }
+ if (e->img != NULL)
+ continue;
+
+ // Now try to load from disk
+ e->img = GetEmoticomImageFromDisk(pack, e, m);
+ if (e->img != NULL)
+ continue;
+
+ // Now try to load from defaults cache
+ for(i = 0; i < pack->images.getCount(); i++)
+ {
+ EmoticonImage *img = pack->images[i];
+ if (img->module == NULL && strcmp(img->name, e->name) == 0)
+ {
+ e->img = GetModuleImage(pack, img, m);
+ break;
+ }
+ }
+ if (e->img != NULL)
+ continue;
+
+ TCHAR err[1024];
+ mir_sntprintf(err, MAX_REGS(err), _T(" *** The pack '%s' does not have the emoticon '") _T(TCHAR_STR_PARAM) _T("' needed by ") _T(TCHAR_STR_PARAM) _T("\n"),
+ pack->description, e->name, m->name);
+ OutputDebugString(err);
+ }
+ }
+}
+
+
+EmoticonPack *GetPack(char *name)
+{
+ EmoticonPack *ret = NULL;
+ for(int i = 0; i < packs.getCount(); i++)
+ {
+ if (strcmpi(packs[i]->name, name) == 0)
+ {
+ ret = packs[i];
+ break;
+ }
+ }
+ return ret;
+}
+
+
+Module *GetModuleByName(const char *name)
+{
+ Module *ret = NULL;
+ for(int i = 0; i < modules.getCount(); i++)
+ {
+ if (stricmp(modules[i]->name, name) == 0)
+ {
+ ret = modules[i];
+ break;
+ }
+ }
+ return ret;
+}
+
+
+Module *GetModule(const char *name)
+{
+ Module *ret = GetModuleByName(name);
+ if (ret == NULL && opts.use_default_pack)
+ ret = GetModuleByName("Default");
+ return ret;
+}
+
+
+int ReplaceEmoticonsService(WPARAM wParam, LPARAM lParam)
+{
+ SMADD_RICHEDIT3 *sre = (SMADD_RICHEDIT3 *) lParam;
+ if (sre == NULL || sre->cbSize < sizeof(SMADD_RICHEDIT3))
+ return FALSE;
+ if (sre->hwndRichEditControl == NULL ||
+ (sre->Protocolname == NULL && sre->hContact == NULL))
+ return FALSE;
+
+
+ DialogMapType::iterator dlgit = dialogData.find(sre->hwndRichEditControl);
+ if (dlgit != dialogData.end())
+ {
+ Dialog *dlg = dlgit->second;
+ ReplaceAllEmoticons(dlg->log, dlg->contact, dlg->module, sre->rangeToReplace == NULL ? 0 : sre->rangeToReplace->cpMin,
+ sre->rangeToReplace == NULL ? -1 : sre->rangeToReplace->cpMax);
+ }
+ else
+ {
+ const char *proto = NULL;
+ if (sre->hContact != NULL)
+ {
+ HANDLE hReal = GetRealContact(sre->hContact);
+ proto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hReal, 0);
+ }
+ if (proto == NULL)
+ proto = sre->Protocolname;
+ if (proto == NULL)
+ return FALSE;
+
+ Module *m = GetModule(proto);
+ if (m == NULL)
+ return FALSE;
+
+ RichEditCtrl rec = {0};
+ LoadRichEdit(&rec, sre->hwndRichEditControl);
+ ReplaceAllEmoticons(rec, GetContact(sre->hContact), m, sre->rangeToReplace == NULL ? 0 : sre->rangeToReplace->cpMin,
+ sre->rangeToReplace == NULL ? -1 : sre->rangeToReplace->cpMax);
+ }
+
+ return TRUE;
+}
+
+
+int GetInfo2Service(WPARAM wParam, LPARAM lParam)
+{
+ SMADD_INFO2 *si = (SMADD_INFO2 *) lParam;
+ if (si == NULL || si->cbSize < sizeof(SMADD_INFO2))
+ return FALSE;
+
+ const char *proto = NULL;
+ if (si->hContact != NULL)
+ {
+ HANDLE hReal = GetRealContact(si->hContact);
+ proto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hReal, 0);
+ }
+ if (proto == NULL)
+ proto = si->Protocolname;
+ if (proto == NULL)
+ return FALSE;
+
+ Module *m = GetModule(proto);
+ if (m == NULL)
+ return FALSE;
+
+ si->NumberOfVisibleSmileys = si->NumberOfSmileys = m->emoticons.getCount();
+
+ return TRUE;
+}
+
+
+void PreMultiply(HBITMAP hBitmap)
+{
+ BYTE *p = NULL;
+ DWORD dwLen;
+ int width, height, x, y;
+ BITMAP bmp;
+ BYTE alpha;
+ BOOL transp = FALSE;
+
+ GetObject(hBitmap, sizeof(bmp), &bmp);
+ width = bmp.bmWidth;
+ height = bmp.bmHeight;
+ dwLen = width * height * 4;
+ p = (BYTE *)malloc(dwLen);
+ if (p != NULL)
+ {
+ GetBitmapBits(hBitmap, dwLen, p);
+
+ for (y = 0; y < height; ++y)
+ {
+ BYTE *px = p + width * 4 * y;
+
+ for (x = 0; x < width; ++x)
+ {
+ alpha = px[3];
+
+ if (alpha < 255)
+ {
+ transp = TRUE;
+
+ px[0] = px[0] * alpha/255;
+ px[1] = px[1] * alpha/255;
+ px[2] = px[2] * alpha/255;
+ }
+
+ px += 4;
+ }
+ }
+
+ if (transp)
+ dwLen = SetBitmapBits(hBitmap, dwLen, p);
+ free(p);
+ }
+}
+
+
+Module::~Module()
+{
+ MIR_FREE(name);
+ MIR_FREE(path);
+
+ for(int i = 0; i < emoticons.getCount(); i++)
+ {
+ delete emoticons[i];
+ }
+ emoticons.destroy();
+}
+
+
+Emoticon::~Emoticon()
+{
+ MIR_FREE(name);
+ MIR_FREE(description);
+
+ for(int i = 0; i < texts.getCount(); i++)
+ {
+ mir_free(texts[i]);
+ }
+ texts.destroy();
+}
+
+
+EmoticonPack::~EmoticonPack()
+{
+ MIR_FREE(name);
+ MIR_FREE(path);
+ MIR_FREE(creator);
+ MIR_FREE(updater_URL);
+
+ for(int i = 0; i < images.getCount(); i++)
+ {
+ delete images[i];
+ }
+ images.destroy();
+}
+
+
+EmoticonImage::~EmoticonImage()
+{
+ Release();
+
+ MIR_FREE(name);
+ MIR_FREE(module);
+ MIR_FREE(relPath);
+}
+
+
+BOOL EmoticonImage::isAvaiableFor(char *module)
+{
+ char tmp[1024];
+ if (module == NULL)
+ mir_snprintf(tmp, MAX_REGS(tmp), "%s\\%s", pack->path, relPath);
+ else
+ mir_snprintf(tmp, MAX_REGS(tmp), "%s\\%s\\%s", pack->path, module, relPath);
+
+ DWORD attrib = GetFileAttributesA(tmp);
+ return !(attrib == 0xFFFFFFFF || (attrib & FILE_ATTRIBUTE_DIRECTORY));
+}
+
+
+BOOL EmoticonImage::isAvaiable()
+{
+ return isAvaiableFor(module);
+}
+
+
+void EmoticonImage::Load(int &max_height, int &max_width)
+{
+ if (img != NULL)
+ {
+ BITMAP bmp;
+ GetObject(img, sizeof(bmp), &bmp);
+
+ max_height = max(max_height, bmp.bmHeight);
+ max_width = max(max_width, bmp.bmWidth);
+
+ return;
+ }
+
+ DWORD transp;
+
+ char tmp[1024];
+ mir_snprintf(tmp, MAX_REGS(tmp), "%s\\%s", pack->path, relPath);
+
+ img = (HBITMAP) CallService(MS_AV_LOADBITMAP32, (WPARAM) &transp, (LPARAM) tmp);
+
+ if (img == NULL)
+ return;
+
+ BITMAP bmp;
+ if (!GetObject(img, sizeof(bmp), &bmp))
+ {
+ DeleteObject(img);
+ img = NULL;
+ return;
+ }
+
+ transparent = (bmp.bmBitsPixel == 32 && transp);
+ if (transparent)
+ PreMultiply(img);
+
+ max_height = max(max_height, bmp.bmHeight);
+ max_width = max(max_width, bmp.bmWidth);
+}
+
+
+void EmoticonImage::Release()
+{
+ if (img == NULL)
+ return;
+
+ DeleteObject(img);
+ img = NULL;
+}
+
+
+Contact * GetContact(HANDLE hContact)
+{
+ if (hContact == NULL)
+ return NULL;
+
+ // Check if already loaded
+ for(int i = 0; i < contacts.getCount(); i++)
+ if (contacts[i]->hContact == hContact)
+ return contacts[i];
+
+ Contact *c = new Contact(hContact);
+ contacts.insert(c);
+
+ // Get from db
+ BOOL pack = FALSE;
+ c->lastId = -1;
+ char setting[256];
+ while(TRUE)
+ {
+ c->lastId++;
+
+ mir_snprintf(setting, MAX_REGS(setting), "%d_Text", c->lastId);
+ DBVARIANT dbv_text = {0};
+ if (DBGetContactSettingTString(hContact, "CustomSmileys", setting, &dbv_text))
+ break;
+
+ mir_snprintf(setting, MAX_REGS(setting), "%d_Path", c->lastId);
+ DBVARIANT dbv_path = {0};
+ if (DBGetContactSettingString(hContact, "CustomSmileys", setting, &dbv_path))
+ {
+ pack = TRUE;
+ DBFreeVariant(&dbv_text);
+ continue;
+ }
+
+ if (GetCustomEmoticon(c, dbv_text.ptszVal) != NULL)
+ {
+ pack = TRUE;
+ }
+ else
+ {
+ CustomEmoticon *ce = new CustomEmoticon();
+ ce->text = mir_tstrdup(dbv_text.ptszVal);
+ ce->path = mir_strdup(dbv_path.pszVal);
+
+ c->emoticons.insert(ce);
+ }
+
+ DBFreeVariant(&dbv_path);
+ DBFreeVariant(&dbv_text);
+ }
+
+ c->lastId--;
+
+ if (pack)
+ {
+ // Re-store then
+ int i;
+ for(i = 0; i < c->emoticons.getCount(); i++)
+ {
+ CustomEmoticon *ce = c->emoticons[i];
+
+ mir_snprintf(setting, MAX_REGS(setting), "%d_Text", i);
+ DBWriteContactSettingTString(c->hContact, "CustomSmileys", setting, ce->text);
+
+ mir_snprintf(setting, MAX_REGS(setting), "%d_Path", i);
+ DBWriteContactSettingString(c->hContact, "CustomSmileys", setting, ce->path);
+ }
+ for(int j = i; j <= c->lastId; j++)
+ {
+ mir_snprintf(setting, MAX_REGS(setting), "%d_Text", j);
+ DBDeleteContactSetting(c->hContact, "CustomSmileys", setting);
+
+ mir_snprintf(setting, MAX_REGS(setting), "%d_Path", j);
+ DBDeleteContactSetting(c->hContact, "CustomSmileys", setting);
+ }
+
+ c->lastId = i - 1;
+ }
+
+ return c;
+}
+
+
+CustomEmoticon *GetCustomEmoticon(Contact *c, TCHAR *text)
+{
+ for(int i = 0; i < c->emoticons.getCount(); i++)
+ {
+ if (lstrcmp(c->emoticons[i]->text, text) == 0)
+ return c->emoticons[i];
+ }
+ return NULL;
+}
+
+
+void DownloadedCustomEmoticon(HANDLE hContact, const char *path)
+{
+ // Mark that it was received
+
+ Contact *c = GetContact(hContact);
+ if (c != NULL)
+ {
+ for(int i = 0; i < c->emoticons.getCount(); i++)
+ {
+ CustomEmoticon *ce = c->emoticons[i];
+ if (stricmp(ce->path, path) == 0)
+ ce->downloading = FALSE;
+ }
+ }
+
+ for(int i = downloading.getCount() - 1; i >= 0; i--)
+ {
+ if (stricmp(downloading[i]->GetFilename(), path) == 0)
+ {
+ OleImage *oimg = downloading[i];
+ oimg->ShowDownloadingIcon(FALSE);
+ oimg->Release();
+
+ downloading.remove(i);
+ }
+ }
+}
+
+int CustomSmileyReceivedEvent(WPARAM wParam, LPARAM lParam)
+{
+ CUSTOMSMILEY *cs = (CUSTOMSMILEY *) lParam;
+ if (cs == NULL || cs->cbSize < sizeof(CUSTOMSMILEY) || cs->pszFilename == NULL || cs->hContact == NULL)
+ return 0;
+
+ // Check if this is the second notification
+ if (!(cs->flags & CUSTOMSMILEY_STATE_RECEIVED))
+ {
+ if (cs->flags & CUSTOMSMILEY_STATE_DOWNLOADED)
+ DownloadedCustomEmoticon(cs->hContact, cs->pszFilename);
+ return 0;
+ }
+
+ // This is the first one
+ if (cs->pszText == NULL)
+ return 0;
+
+ // Get data
+ Contact *c = GetContact(cs->hContact);
+
+ TCHAR *text;
+ if (cs->flags & CUSTOMSMILEY_UNICODE)
+ text = mir_u2t(cs->pwszText);
+ else
+ text = mir_a2t(cs->pszText);
+
+ // Create it
+ CustomEmoticon *ce = GetCustomEmoticon(c, text);
+ if (ce != NULL)
+ {
+ MIR_FREE(ce->path);
+ ce->path = mir_strdup(cs->pszFilename);
+
+ MIR_FREE(text);
+ }
+ else
+ {
+ ce = new CustomEmoticon();
+ ce->text = text;
+ ce->path = mir_strdup(cs->pszFilename);
+
+ c->emoticons.insert(ce);
+ c->lastId++;
+ }
+
+ // Check if need to download
+ if (!(cs->flags & CUSTOMSMILEY_STATE_DOWNLOADED) && GetFileAttributesA(cs->pszFilename) == INVALID_FILE_ATTRIBUTES)
+ {
+ // Request emoticon download
+ cs->download = TRUE;
+ ce->downloading = TRUE;
+ }
+
+ // Store in DB
+ char setting[256];
+ mir_snprintf(setting, MAX_REGS(setting), "%d_Text", c->lastId);
+ DBWriteContactSettingTString(c->hContact, "CustomSmileys", setting, ce->text);
+
+ mir_snprintf(setting, MAX_REGS(setting), "%d_Path", c->lastId);
+ DBWriteContactSettingString(c->hContact, "CustomSmileys", setting, ce->path);
+
+ return 0;
+}
diff --git a/Plugins/emoticons/emoticons.dsp b/Plugins/emoticons/emoticons.dsp
new file mode 100644
index 0000000..2628749
--- /dev/null
+++ b/Plugins/emoticons/emoticons.dsp
@@ -0,0 +1,259 @@
+# Microsoft Developer Studio Project File - Name="emoticons" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
+
+CFG=emoticons - Win32 Release
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "emoticons.mak".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "emoticons.mak" CFG="emoticons - Win32 Release"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "emoticons - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "emoticons - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "emoticons - Win32 Unicode Debug" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE "emoticons - Win32 Unicode Release" (based on "Win32 (x86) Dynamic-Link Library")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+MTL=midl.exe
+RSC=rc.exe
+
+!IF "$(CFG)" == "emoticons - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /MD /W3 /GX /O1 /YX /FD /c
+# SUBTRACT BASE CPP /Fr
+# ADD CPP /nologo /G4 /MT /W3 /GX /O2 /Ob0 /I "../../include" /I "sdk" /D "WIN32" /D "W32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Fr /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 user32.lib shell32.lib wininet.lib gdi32.lib /nologo /base:"0x67100000" /dll /machine:I386 /filealign:0x200
+# SUBTRACT BASE LINK32 /pdb:none /map
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib msimg32.lib comctl32.lib ole32.lib oleaut32.lib /nologo /base:"0x3EC20000" /dll /map /debug /debugtype:both /machine:I386 /out:"..\..\bin\release\Plugins\emoticons.dll" /pdbtype:sept /filealign:0x200 /ALIGN:4096 /ignore:4108
+# SUBTRACT LINK32 /profile /pdb:none
+
+!ELSEIF "$(CFG)" == "emoticons - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /MT /W3 /GX /O2 /Ob0 /I "../../include" /FR /YX /FD /c
+# ADD CPP /nologo /G4 /MTd /W3 /GX /ZI /Od /I "../../include" /I "sdk" /D "WIN32" /D "W32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..bin\release\Plugins\emoticons.dll" /filealign:0x200 /ALIGN:4096 /ignore:4108
+# SUBTRACT BASE LINK32 /profile /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib msimg32.lib comctl32.lib ole32.lib oleaut32.lib /nologo /base:"0x3EC20000" /dll /incremental:yes /debug /machine:I386 /out:"..\..\bin\debug\Plugins\emoticons.dll" /filealign:0x200 /ALIGN:4096 /ignore:4108
+# SUBTRACT LINK32 /profile /pdb:none
+
+!ELSEIF "$(CFG)" == "emoticons - Win32 Unicode Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "emoticons___Win32_Unicode_Debug"
+# PROP BASE Intermediate_Dir "emoticons___Win32_Unicode_Debug"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Unicode_Debug"
+# PROP Intermediate_Dir "Unicode_Debug"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /MTd /W3 /GX /ZI /Od /I "../../include" /FR /YX /FD /c
+# ADD CPP /nologo /G4 /MTd /W3 /GX /ZI /Od /I "../../include" /I "sdk" /D "WIN32" /D "W32" /D "_DEBUG" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /D "_USRDLL" /FR /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x32100000" /dll /incremental:yes /debug /machine:I386 /out:"..\..\bin\debug\Plugins\emoticons.dll" /filealign:0x200 /ALIGN:4096 /ignore:4108
+# SUBTRACT BASE LINK32 /profile /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib msimg32.lib comctl32.lib ole32.lib oleaut32.lib /nologo /base:"0x3EC20000" /dll /incremental:yes /debug /machine:I386 /out:"..\..\bin\debug unicode\Plugins\emoticonsW.dll" /filealign:0x200 /ALIGN:4096 /ignore:4108
+# SUBTRACT LINK32 /profile /pdb:none
+
+!ELSEIF "$(CFG)" == "emoticons - Win32 Unicode Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "emoticons___Win32_Unicode_Release"
+# PROP BASE Intermediate_Dir "emoticons___Win32_Unicode_Release"
+# PROP BASE Ignore_Export_Lib 0
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Unicode_Release"
+# PROP Intermediate_Dir "Unicode_Release"
+# PROP Ignore_Export_Lib 0
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /G4 /MT /W3 /GX /O2 /Ob0 /I "../../include" /Fr /YX /FD /c
+# ADD CPP /nologo /G4 /MT /W3 /GX /O2 /Ob0 /I "../../include" /I "sdk" /D "WIN32" /D "W32" /D "NDEBUG" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /D "_USRDLL" /Fr /YX /FD /c
+# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
+# ADD BASE RSC /l 0x417 /d "NDEBUG"
+# ADD RSC /l 0x417 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 comctl32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x32100000" /dll /map /machine:I386 /out:"..\..\bin\release\Plugins\emoticons.dll" /filealign:0x200 /ALIGN:4096 /ignore:4108
+# SUBTRACT BASE LINK32 /profile /pdb:none
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib msimg32.lib comctl32.lib ole32.lib oleaut32.lib /nologo /base:"0x3EC20000" /dll /map /debug /debugtype:both /machine:I386 /out:"..\..\bin\release unicode\Plugins\emoticonsW.dll" /pdbtype:sept /filealign:0x200 /ALIGN:4096 /ignore:4108
+# SUBTRACT LINK32 /profile /pdb:none
+
+!ENDIF
+
+# Begin Target
+
+# Name "emoticons - Win32 Release"
+# Name "emoticons - Win32 Debug"
+# Name "emoticons - Win32 Unicode Debug"
+# Name "emoticons - Win32 Unicode Release"
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\commons.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\m_emoticons.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\utils\mir_icons.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\utils\mir_memory.h
+# End Source File
+# Begin Source File
+
+SOURCE=..\utils\mir_options.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\OleImage.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\options.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\resource.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\selwin.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# Begin Source File
+
+SOURCE=.\resource.rc
+# End Source File
+# End Group
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\emoticons.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\utils\mir_icons.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\utils\mir_memory.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=..\utils\mir_options.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\OleImage.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\options.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\selwin.cpp
+# End Source File
+# End Group
+# Begin Group "Docs"
+
+# PROP Default_Filter ""
+# Begin Source File
+
+SOURCE=.\Docs\emoticons_changelog.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\Docs\emoticons_readme.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\Docs\emoticons_version.txt
+# End Source File
+# Begin Source File
+
+SOURCE=.\Docs\langpack_emoticons.txt
+# End Source File
+# End Group
+# End Target
+# End Project
diff --git a/Plugins/emoticons/emoticons.dsw b/Plugins/emoticons/emoticons.dsw
new file mode 100644
index 0000000..8f32834
--- /dev/null
+++ b/Plugins/emoticons/emoticons.dsw
@@ -0,0 +1,29 @@
+Microsoft Developer Studio Workspace File, Format Version 6.00
+# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
+
+###############################################################################
+
+Project: "emoticons"=.\emoticons.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Global:
+
+Package=<5>
+{{{
+}}}
+
+Package=<3>
+{{{
+}}}
+
+###############################################################################
+
diff --git a/Plugins/emoticons/emoticons.sln b/Plugins/emoticons/emoticons.sln
new file mode 100644
index 0000000..abbbeab
--- /dev/null
+++ b/Plugins/emoticons/emoticons.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "emoticons", "emoticons.vcproj", "{8A52EF1C-B62C-421F-BA6D-C0B3EA7B89F8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ Unicode Debug|Win32 = Unicode Debug|Win32
+ Unicode Release|Win32 = Unicode Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {8A52EF1C-B62C-421F-BA6D-C0B3EA7B89F8}.Debug|Win32.ActiveCfg = Debug|Win32
+ {8A52EF1C-B62C-421F-BA6D-C0B3EA7B89F8}.Debug|Win32.Build.0 = Debug|Win32
+ {8A52EF1C-B62C-421F-BA6D-C0B3EA7B89F8}.Release|Win32.ActiveCfg = Release|Win32
+ {8A52EF1C-B62C-421F-BA6D-C0B3EA7B89F8}.Release|Win32.Build.0 = Release|Win32
+ {8A52EF1C-B62C-421F-BA6D-C0B3EA7B89F8}.Unicode Debug|Win32.ActiveCfg = Unicode Debug|Win32
+ {8A52EF1C-B62C-421F-BA6D-C0B3EA7B89F8}.Unicode Debug|Win32.Build.0 = Unicode Debug|Win32
+ {8A52EF1C-B62C-421F-BA6D-C0B3EA7B89F8}.Unicode Release|Win32.ActiveCfg = Unicode Release|Win32
+ {8A52EF1C-B62C-421F-BA6D-C0B3EA7B89F8}.Unicode Release|Win32.Build.0 = Unicode Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Plugins/emoticons/emoticons.vcproj b/Plugins/emoticons/emoticons.vcproj
new file mode 100644
index 0000000..12423a7
--- /dev/null
+++ b/Plugins/emoticons/emoticons.vcproj
@@ -0,0 +1,775 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="8,00"
+ Name="emoticons"
+ ProjectGUID="{8A52EF1C-B62C-421F-BA6D-C0B3EA7B89F8}"
+ RootNamespace="emoticons"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Unicode Release|Win32"
+ OutputDirectory=".\Unicode_Release"
+ IntermediateDirectory=".\Unicode_Release"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Unicode_Release/emoticons.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="0"
+ AdditionalIncludeDirectories="../../include,sdk"
+ PreprocessorDefinitions="WIN32;W32;NDEBUG;_WINDOWS;UNICODE;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Unicode_Release/emoticons.pch"
+ AssemblerListingLocation=".\Unicode_Release/"
+ ObjectFile=".\Unicode_Release/"
+ ProgramDataBaseFileName=".\Unicode_Release/"
+ BrowseInformation="2"
+ BrowseInformationFile=".\Unicode_Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1047"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/ALIGN:4096 /filealign:0x200 /ignore:4108 "
+ AdditionalDependencies="msimg32.lib comctl32.lib"
+ OutputFile="..\..\bin\release unicode\Plugins\emoticonsW.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Unicode_Release/emoticonsW.pdb"
+ GenerateMapFile="true"
+ MapFileName=".\Unicode_Release/emoticonsW.map"
+ BaseAddress="0x3EC20000"
+ ImportLibrary=".\Unicode_Release/emoticonsW.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Unicode_Release/emoticons.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Unicode Debug|Win32"
+ OutputDirectory=".\Unicode_Debug"
+ IntermediateDirectory=".\Unicode_Debug"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Unicode_Debug/emoticons.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include,sdk"
+ PreprocessorDefinitions="WIN32;W32;_DEBUG;_WINDOWS;UNICODE;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
+ MinimalRebuild="true"
+ RuntimeLibrary="1"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Unicode_Debug/emoticons.pch"
+ AssemblerListingLocation=".\Unicode_Debug/"
+ ObjectFile=".\Unicode_Debug/"
+ ProgramDataBaseFileName=".\Unicode_Debug/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1047"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/ALIGN:4096 /filealign:0x200 /ignore:4108 "
+ AdditionalDependencies="msimg32.lib comctl32.lib"
+ OutputFile="..\..\bin\debug unicode\Plugins\emoticonsW.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Unicode_Debug/emoticonsW.pdb"
+ BaseAddress="0x3EC20000"
+ ImportLibrary=".\Unicode_Debug/emoticonsW.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Unicode_Debug/emoticons.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory=".\Release"
+ IntermediateDirectory=".\Release"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Release/emoticons.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="0"
+ AdditionalIncludeDirectories="../../include,sdk"
+ PreprocessorDefinitions="WIN32;W32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ PrecompiledHeaderFile=".\Release/emoticons.pch"
+ AssemblerListingLocation=".\Release/"
+ ObjectFile=".\Release/"
+ ProgramDataBaseFileName=".\Release/"
+ BrowseInformation="2"
+ BrowseInformationFile=".\Release/"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1047"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/ALIGN:4096 /filealign:0x200 /ignore:4108 "
+ AdditionalDependencies="msimg32.lib comctl32.lib"
+ OutputFile="..\..\bin\release\Plugins\emoticons.dll"
+ LinkIncremental="1"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Release/emoticons.pdb"
+ GenerateMapFile="true"
+ MapFileName=".\Release/emoticons.map"
+ BaseAddress="0x3EC20000"
+ ImportLibrary=".\Release/emoticons.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Release/emoticons.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory=".\Debug"
+ IntermediateDirectory=".\Debug"
+ ConfigurationType="2"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ PreprocessorDefinitions="NDEBUG"
+ MkTypLibCompatible="true"
+ SuppressStartupBanner="true"
+ TargetEnvironment="1"
+ TypeLibraryName=".\Debug/emoticons.tlb"
+ HeaderFileName=""
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="../../include,sdk"
+ PreprocessorDefinitions="WIN32;W32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
+ RuntimeLibrary="1"
+ PrecompiledHeaderFile=".\Debug/emoticons.pch"
+ AssemblerListingLocation=".\Debug/"
+ ObjectFile=".\Debug/"
+ ProgramDataBaseFileName=".\Debug/"
+ BrowseInformation="1"
+ WarningLevel="3"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1047"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLinkerTool"
+ AdditionalOptions="/ALIGN:4096 /filealign:0x200 /ignore:4108 "
+ AdditionalDependencies="msimg32.lib comctl32.lib"
+ OutputFile="..\..\bin\debug\Plugins\emoticons.dll"
+ LinkIncremental="2"
+ SuppressStartupBanner="true"
+ GenerateDebugInformation="true"
+ ProgramDatabaseFile=".\Debug/emoticons.pdb"
+ BaseAddress="0x3EC20000"
+ ImportLibrary=".\Debug/emoticons.lib"
+ TargetMachine="1"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCManifestTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ SuppressStartupBanner="true"
+ OutputFile=".\Debug/emoticons.bsc"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCAppVerifierTool"
+ />
+ <Tool
+ Name="VCWebDeploymentTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl"
+ >
+ <File
+ RelativePath="commons.h"
+ >
+ </File>
+ <File
+ RelativePath="m_emoticons.h"
+ >
+ </File>
+ <File
+ RelativePath="..\utils\mir_icons.h"
+ >
+ </File>
+ <File
+ RelativePath="..\utils\mir_memory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\utils\mir_options.h"
+ >
+ </File>
+ <File
+ RelativePath="OleImage.h"
+ >
+ </File>
+ <File
+ RelativePath="options.h"
+ >
+ </File>
+ <File
+ RelativePath="resource.h"
+ >
+ </File>
+ <File
+ RelativePath=".\selwin.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Resource Files"
+ Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+ >
+ <File
+ RelativePath="resource.rc"
+ >
+ <FileConfiguration
+ Name="Unicode Release|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Debug|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ >
+ <File
+ RelativePath="emoticons.cpp"
+ >
+ <FileConfiguration
+ Name="Unicode Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\utils\mir_icons.cpp"
+ >
+ <FileConfiguration
+ Name="Unicode Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\utils\mir_memory.cpp"
+ >
+ <FileConfiguration
+ Name="Unicode Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="..\utils\mir_options.cpp"
+ >
+ <FileConfiguration
+ Name="Unicode Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="OleImage.cpp"
+ >
+ <FileConfiguration
+ Name="Unicode Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath="options.cpp"
+ >
+ <FileConfiguration
+ Name="Unicode Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Unicode Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Release|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ <FileConfiguration
+ Name="Debug|Win32"
+ >
+ <Tool
+ Name="VCCLCompilerTool"
+ AdditionalIncludeDirectories=""
+ PreprocessorDefinitions=""
+ />
+ </FileConfiguration>
+ </File>
+ <File
+ RelativePath=".\selwin.cpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Docs"
+ >
+ <File
+ RelativePath="Docs\emoticons_changelog.txt"
+ >
+ </File>
+ <File
+ RelativePath="Docs\emoticons_readme.txt"
+ >
+ </File>
+ <File
+ RelativePath="Docs\emoticons_version.txt"
+ >
+ </File>
+ <File
+ RelativePath="Docs\langpack_emoticons.txt"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Plugins/emoticons/m_emoticons.h b/Plugins/emoticons/m_emoticons.h
new file mode 100644
index 0000000..66b4a34
--- /dev/null
+++ b/Plugins/emoticons/m_emoticons.h
@@ -0,0 +1,27 @@
+/*
+Copyright (C) 2008 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __M_EMOTICONS_H__
+# define __M_EMOTICONS_H__
+
+
+
+
+#endif // __M_EMOTICONS_H__
diff --git a/Plugins/emoticons/options.cpp b/Plugins/emoticons/options.cpp
new file mode 100644
index 0000000..6c888ac
--- /dev/null
+++ b/Plugins/emoticons/options.cpp
@@ -0,0 +1,376 @@
+/*
+Copyright (C) 2008 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "commons.h"
+
+#include "options.h"
+
+
+
+// Prototypes /////////////////////////////////////////////////////////////////////////////////////
+
+HANDLE hOptHook = NULL;
+
+Options opts;
+
+
+static BOOL CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+
+static OptPageControl optionsControls[] = {
+ { &opts.replace_in_input, CONTROL_CHECKBOX, IDC_INPUT_TOO, "ReplaceInInput", TRUE },
+ { &opts.use_default_pack, CONTROL_CHECKBOX, IDC_USE_DEFAULT_PACK, "UseDefaultPack", TRUE },
+ { &opts.only_replace_isolated, CONTROL_CHECKBOX, IDC_ONLY_ISOLATED, "OnlyReplaceIsolatedEmoticons", FALSE },
+};
+
+static UINT optionsExpertControls[] = {
+ IDC_INPUT_TOO, IDC_USE_DEFAULT_PACK, IDC_ONLY_ISOLATED
+};
+
+
+// Functions //////////////////////////////////////////////////////////////////////////////////////
+
+
+int InitOptionsCallback(WPARAM wParam,LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp;
+
+ ZeroMemory(&odp,sizeof(odp));
+ odp.cbSize=sizeof(odp);
+ odp.position=0;
+ odp.hInstance=hInst;
+ odp.ptszGroup = TranslateT("Message Sessions");
+ odp.ptszTitle = TranslateT("Emoticons");
+ odp.pfnDlgProc = OptionsDlgProc;
+ odp.pszTemplate = MAKEINTRESOURCEA(IDD_OPTIONS);
+ odp.flags = ODPF_BOLDGROUPS | ODPF_TCHAR;
+ odp.expertOnlyControls = optionsExpertControls;
+ odp.nExpertOnlyControls = MAX_REGS(optionsExpertControls);
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+
+ return 0;
+}
+
+
+void InitOptions()
+{
+ LoadOptions();
+
+ hOptHook = HookEvent(ME_OPT_INITIALISE, InitOptionsCallback);
+}
+
+
+void DeInitOptions()
+{
+ UnhookEvent(hOptHook);
+}
+
+
+void LoadOptions()
+{
+ LoadOpts(optionsControls, MAX_REGS(optionsControls), MODULE_NAME);
+
+ opts.pack[0] = '\0';
+
+ DBVARIANT dbv;
+ if (!DBGetContactSettingString(NULL, MODULE_NAME, "DefaultPack", &dbv))
+ {
+ strncpy(opts.pack, dbv.pszVal, MAX_REGS(opts.pack)-1);
+ opts.pack[MAX_REGS(opts.pack)-1] = _T('\0');
+ DBFreeVariant(&dbv);
+ }
+}
+
+
+#define BORDER 5
+
+
+struct PackData
+{
+ EmoticonPack *pack;
+ int max_height;
+ int max_width;
+};
+
+
+static BOOL CALLBACK OptionsDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ if (packs.getCount() <= 0)
+ break;
+
+ int sel = 0;
+ for(int i = 0; i < packs.getCount(); i++)
+ {
+ PackData *pd = new PackData();
+ pd->pack = packs[i];
+
+ pd->max_height = 0;
+ pd->max_width = 0;
+ srand(time(NULL));
+ int prob = (pd->pack->images.getCount() - 15) / 30 + 1;
+ for(int j = 0, count = 0; j < pd->pack->images.getCount() && count < 15; j++) {
+ if (rand() % prob != 0)
+ continue;
+ pd->pack->images[j]->Load(pd->max_height, pd->max_width);
+ count++;
+ }
+
+ SendDlgItemMessage(hwndDlg, IDC_PACK, LB_ADDSTRING, 0, (LONG) pd);
+ SendDlgItemMessage(hwndDlg, IDC_PACK, LB_SETITEMDATA, i, (LONG) pd);
+
+ if (strcmp(opts.pack, pd->pack->name) == 0)
+ sel = i;
+ }
+ SendDlgItemMessage(hwndDlg, IDC_PACK, LB_SETCURSEL, sel, 0);
+
+ break;
+ }
+
+ case WM_COMMAND:
+ {
+ if(LOWORD(wParam) == IDC_GETMORE)
+ CallService(MS_UTILS_OPENURL, 1, (LPARAM) "http://addons.miranda-im.org/index.php?action=display&id=41");
+
+ if (LOWORD(wParam) == IDC_PACK
+ && (HIWORD(wParam) == LBN_SELCHANGE && (HWND)lParam == GetFocus()))
+ {
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ return 0;
+ }
+
+ break;
+ }
+
+ case WM_NOTIFY:
+ {
+ if (packs.getCount() <= 0)
+ break;
+
+ LPNMHDR lpnmhdr = (LPNMHDR)lParam;
+
+ if (lpnmhdr->idFrom == 0 && lpnmhdr->code == PSN_APPLY)
+ {
+ int sel = SendDlgItemMessage(hwndDlg, IDC_PACK, LB_GETCURSEL, 0, 0);
+ if (sel >= packs.getCount())
+ sel = 0;
+
+ PackData *pd = (PackData *) SendDlgItemMessage(hwndDlg, IDC_PACK, LB_GETITEMDATA, sel, 0);
+ EmoticonPack *pack = (pd == NULL ? NULL : pd->pack);
+ if (pack == NULL)
+ pack = packs[0];
+
+ DBWriteContactSettingString(NULL, MODULE_NAME, "DefaultPack", pack->name);
+ strcpy(opts.pack, pack->name);
+ FillModuleImages(pack);
+ }
+
+ break;
+ }
+
+ case WM_MEASUREITEM:
+ {
+ MEASUREITEMSTRUCT *mi = (MEASUREITEMSTRUCT *) lParam;
+ if (mi == NULL)
+ break;
+
+ PackData *pd = (PackData *) mi->itemData;
+ mi->itemHeight = 2 * BORDER;
+
+ if (pd->max_height > 0)
+ mi->itemHeight += pd->max_height + BORDER;
+
+ // Get font
+ HFONT hFont = (HFONT) SendMessage(GetDlgItem(hwndDlg, IDC_PACK), WM_GETFONT, 0, 0);
+
+ HDC hdc = GetDC(GetDlgItem(hwndDlg, IDC_PACK));
+
+ // Create one +2px bold
+ LOGFONT lf = {0};
+ GetObject(hFont, sizeof(lf), &lf);
+ lf.lfHeight = - abs(lf.lfHeight) - MulDiv(2, GetDeviceCaps(hdc, LOGPIXELSY), 72);
+ lf.lfWidth = 0;
+ lf.lfWeight = FW_BOLD;
+
+ hFont = CreateFontIndirect(&lf);
+
+ HFONT hOldFont = (HFONT) SelectObject(hdc, hFont);
+
+ // Get its metrics
+ TEXTMETRIC tm = {0};
+ GetTextMetrics(hdc, &tm);
+
+ SelectObject(hdc, hOldFont);
+ ReleaseDC(GetDlgItem(hwndDlg, IDC_PACK), hdc);
+ DeleteObject(hFont);
+
+ mi->itemHeight += tm.tmHeight;
+
+ return TRUE;
+ }
+
+ case WM_DRAWITEM:
+ {
+ DRAWITEMSTRUCT *di = (DRAWITEMSTRUCT *) lParam;
+ if (di->itemAction == ODA_FOCUS)
+ break;
+
+ PackData *pd = (PackData *) di->itemData;
+ HDC hdc = di->hDC;
+ RECT rc = di->rcItem;
+
+ if (di->itemID == -1 || (di->itemState & ODS_SELECTED))
+ FillRect(hdc, &rc, GetSysColorBrush(COLOR_HIGHLIGHT));
+ else
+ FillRect(hdc, &rc, GetSysColorBrush(COLOR_WINDOW));
+
+ if (di->itemID == -1)
+ return TRUE;
+
+ int old_bk_mode = SetBkMode(hdc, TRANSPARENT);
+ COLORREF old_color = GetTextColor(hdc);
+
+ rc.left += BORDER;
+ rc.right -= BORDER;
+ rc.top += BORDER;
+ rc.bottom -= BORDER;
+
+ HRGN rgn = CreateRectRgnIndirect(&rc);
+ SelectClipRgn(hdc, rgn);
+
+ // Get font
+ HFONT hFont = (HFONT) SendMessage(GetDlgItem(hwndDlg, IDC_PACK), WM_GETFONT, 0, 0);
+
+ // Create one +2px bold
+ LOGFONT lf = {0};
+ GetObject(hFont, sizeof(lf), &lf);
+ lf.lfHeight = - abs(lf.lfHeight) - MulDiv(2, GetDeviceCaps(hdc, LOGPIXELSY), 72);
+ lf.lfWidth = 0;
+ lf.lfWeight = FW_BOLD;
+
+ HFONT hBigFont = CreateFontIndirect(&lf);
+
+ // Get its metrics
+ HFONT old_font = (HFONT) SelectObject(hdc, hBigFont);
+
+ RECT rc_tmp = { rc.left, rc.top, 0xFFFF, 0xFFFF };
+ DrawText(hdc, pd->pack->description, lstrlen(pd->pack->description), &rc_tmp, DT_CALCRECT | DT_NOPREFIX | DT_TOP | DT_SINGLELINE);
+
+ DrawText(hdc, pd->pack->description, lstrlen(pd->pack->description), &rc_tmp, DT_NOPREFIX | DT_BOTTOM | DT_SINGLELINE);
+
+ rc_tmp.left = rc_tmp.right + BORDER;
+ rc_tmp.right = rc.right;
+
+ if (pd->pack->creator != NULL && pd->pack->creator[0] != _T('\0'))
+ {
+ TEXTMETRIC tmb = {0};
+ GetTextMetrics(hdc, &tmb);
+
+ SelectObject(hdc, hFont);
+
+ TEXTMETRIC tms = {0};
+ GetTextMetrics(hdc, &tms);
+
+ rc_tmp.bottom -= tmb.tmDescent - tms.tmDescent;
+
+ TCHAR tmp[256];
+ mir_sntprintf(tmp, MAX_REGS(tmp), TranslateT("by %s"), pd->pack->creator);
+ DrawText(hdc, tmp, lstrlen(tmp), &rc_tmp, DT_NOPREFIX | DT_BOTTOM | DT_SINGLELINE);
+ }
+
+ rc_tmp.left = rc.left;
+ rc_tmp.right = rc.right;
+ rc_tmp.top = rc_tmp.bottom + BORDER;
+ rc_tmp.bottom = rc.bottom;
+
+ for(int i = 0; i < pd->pack->images.getCount(); i++)
+ {
+ EmoticonImage *img = pd->pack->images[i];
+ if (img == NULL || img->img == NULL)
+ continue;
+
+ BITMAP bmp;
+ GetObject(img->img, sizeof(bmp), &bmp);
+
+ if (rc_tmp.left + bmp.bmWidth > rc_tmp.right)
+ break;
+
+ HDC hdc_img = CreateCompatibleDC(hdc);
+ HBITMAP old_bmp = (HBITMAP) SelectObject(hdc_img, img->img);
+
+ int x = rc_tmp.left;
+ int y = rc_tmp.top + ((rc_tmp.bottom - rc_tmp.top) - bmp.bmHeight) / 2;
+
+ if (img->transparent)
+ {
+ BLENDFUNCTION bf = {0};
+ bf.SourceConstantAlpha = 255;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ AlphaBlend(hdc, x, y, bmp.bmWidth, bmp.bmHeight, hdc_img, 0, 0, bmp.bmWidth, bmp.bmHeight, bf);
+ }
+ else
+ {
+ BitBlt(hdc, x, y, bmp.bmWidth, bmp.bmHeight, hdc_img, 0, 0, SRCCOPY);
+ }
+
+ SelectObject(hdc_img, old_bmp);
+ DeleteDC(hdc_img);
+
+ rc_tmp.left += bmp.bmWidth + 2;
+ }
+
+ SelectClipRgn(hdc, NULL);
+ DeleteObject(rgn);
+ SelectObject(hdc, old_font);
+ SetTextColor(hdc, old_color);
+ SetBkMode(hdc, old_bk_mode);
+ DeleteObject(hBigFont);
+
+ return TRUE;
+ }
+
+ case WM_DESTROY:
+ {
+ if (packs.getCount() <= 0)
+ break;
+
+ for(int i = 0; i < packs.getCount(); i++)
+ {
+ PackData *pd = (PackData *) SendDlgItemMessage(hwndDlg, IDC_PACK, LB_GETITEMDATA, i, 0);
+ if (pd != NULL)
+ delete pd;
+
+ if (strcmp(opts.pack, packs[i]->name) != 0)
+ for(int j = 0; j < packs[i]->images.getCount(); j++)
+ if (packs[i]->images[j] != NULL)
+ packs[i]->images[j]->Release();
+ }
+
+ break;
+ }
+ }
+
+ return SaveOptsDlgProc(optionsControls, MAX_REGS(optionsControls), MODULE_NAME, hwndDlg, msg, wParam, lParam);
+}
+
+
diff --git a/Plugins/emoticons/options.h b/Plugins/emoticons/options.h
new file mode 100644
index 0000000..259c357
--- /dev/null
+++ b/Plugins/emoticons/options.h
@@ -0,0 +1,51 @@
+/*
+Copyright (C) 2008 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __OPTIONS_H__
+# define __OPTIONS_H__
+
+
+#include <windows.h>
+
+
+struct Options {
+ char pack[128];
+ BOOL replace_in_input;
+ BOOL use_default_pack;
+ BOOL only_replace_isolated;
+};
+
+extern Options opts;
+
+
+// Initializations needed by options
+void InitOptions();
+
+// Deinitializations needed by options
+void DeInitOptions();
+
+
+// Loads the options from DB
+// It don't need to be called, except in some rare cases
+void LoadOptions();
+
+
+
+#endif // __OPTIONS_H__
diff --git a/Plugins/emoticons/resource.h b/Plugins/emoticons/resource.h
new file mode 100644
index 0000000..1f76c5e
--- /dev/null
+++ b/Plugins/emoticons/resource.h
@@ -0,0 +1,29 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDD_OPTIONS 119
+#define IDD_OPTIONS_OLD 120
+#define IDD_EMOTICON_SELECTION 126
+#define IDC_INPUT_TOO 1060
+#define IDC_IGNORE_UPPERCASE 1065
+#define IDC_AUTO_USER 1066
+#define IDC_USE_DEFAULT_PACK 1066
+#define IDC_PACK 1075
+#define IDC_GETMORE 1076
+#define IDC_EMOTICONS 1080
+#define IDC_ONLY_ISOLATED 1086
+#define IDC_STATIC -1
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC 1
+#define _APS_3D_CONTROLS 1
+#define _APS_NEXT_RESOURCE_VALUE 128
+#define _APS_NEXT_COMMAND_VALUE 40005
+#define _APS_NEXT_CONTROL_VALUE 1087
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Plugins/emoticons/resource.rc b/Plugins/emoticons/resource.rc
new file mode 100644
index 0000000..c508fef
--- /dev/null
+++ b/Plugins/emoticons/resource.rc
@@ -0,0 +1,155 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "resource.h"
+#include "winresrc.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Neutral resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
+#ifdef _WIN32
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPTIONS_OLD DIALOGEX 0, 0, 252, 105
+STYLE DS_FIXEDSYS | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg", 0, 0, 0x1
+BEGIN
+ GROUPBOX " Emoticons ",IDC_EMOTICONS,1,5,250,99
+ LTEXT "Pack:",IDC_STATIC,11,20,48,8
+ COMBOBOX IDC_PACK,63,18,177,60,CBS_DROPDOWNLIST | WS_VSCROLL |
+ WS_TABSTOP
+ CONTROL "Replace emoticons in text input area too",IDC_INPUT_TOO,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,40,230,10
+ CONTROL "Use default emoticon pack for unknown protocols",
+ IDC_USE_DEFAULT_PACK,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,10,52,230,10
+ CONTROL "Ignore words in UPPER CASE",IDC_IGNORE_UPPERCASE,"Button",
+ BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,10,64,230,
+ 10
+ CONTROL "Download more emoticon packs",IDC_GETMORE,"Hyperlink",
+ WS_TABSTOP | 0x1,10,85,230,12
+END
+
+IDD_EMOTICON_SELECTION DIALOGEX 0, 0, 188, 90
+STYLE WS_POPUP | WS_VISIBLE | WS_BORDER
+EXSTYLE WS_EX_NOPARENTNOTIFY
+FONT 8, "MS Sans Serif", 0, 0, 0x1
+BEGIN
+END
+
+IDD_OPTIONS DIALOGEX 0, 0, 293, 228
+STYLE DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_VISIBLE
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LISTBOX IDC_PACK,7,2,277,148,LBS_OWNERDRAWVARIABLE |
+ LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Replace emoticons in text input area too",IDC_INPUT_TOO,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,160,277,10
+ CONTROL "Use default emoticon pack for unknown protocols",
+ IDC_USE_DEFAULT_PACK,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,7,172,277,10
+ CONTROL "Only replace emoticons surrounded by spaces",
+ IDC_ONLY_ISOLATED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
+ 7,184,277,10
+ CONTROL "Download more emoticon packs",IDC_GETMORE,"Hyperlink",
+ WS_TABSTOP | 0x1,7,205,277,12
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_OPTIONS_OLD, DIALOG
+ BEGIN
+ LEFTMARGIN, 1
+ RIGHTMARGIN, 251
+ TOPMARGIN, 1
+ BOTTOMMARGIN, 104
+ END
+
+ IDD_OPTIONS, DIALOG
+ BEGIN
+ LEFTMARGIN, 1
+ TOPMARGIN, 1
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // Neutral resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (Canada) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENC)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_CAN
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "#include ""resource.h""\r\n"
+ "#include ""winresrc.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // English (Canada) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Plugins/emoticons/sdk/anismiley.tlh b/Plugins/emoticons/sdk/anismiley.tlh
new file mode 100644
index 0000000..2318a20
--- /dev/null
+++ b/Plugins/emoticons/sdk/anismiley.tlh
@@ -0,0 +1,78 @@
+// Created by Microsoft (R) C/C++ Compiler Version 14.00.50727.42 (48e453e7).
+//
+// c:\desenvolvimento\miranda\plugins\emoticons\unicode_debug\anismiley.tlh
+//
+// C++ source equivalent of Win32 type library C:\Desenvolvimento\Miranda\bin\debug unicode\Plugins\AniSmiley.dll
+// compiler-generated file created 02/07/08 at 01:32:06 - DO NOT EDIT!
+
+#pragma once
+#pragma pack(push, 8)
+
+#include <comdef.h>
+
+//
+// Forward references and typedefs
+//
+
+struct __declspec(uuid("518667de-537d-4790-8e93-48b9ce8ebad2"))
+/* LIBID */ __GifSmiley;
+struct /* coclass */ CGifSmileyCtrl;
+struct __declspec(uuid("58b32d03-1bd2-4840-992e-9ae799fd4ade"))
+/* interface */ ITooltipData;
+struct __declspec(uuid("cb64102b-8ce4-4a55-b050-131c435a3a3f"))
+/* interface */ IGifSmileyCtrl;
+
+//
+// Smart pointer typedef declarations
+//
+
+_COM_SMARTPTR_TYPEDEF(ITooltipData, __uuidof(ITooltipData));
+_COM_SMARTPTR_TYPEDEF(IGifSmileyCtrl, __uuidof(IGifSmileyCtrl));
+
+//
+// Type library items
+//
+
+struct __declspec(uuid("db35dd77-55e2-4905-8075-eb351bb5cbc1"))
+CGifSmileyCtrl;
+ // interface ITooltipData
+ // [ default ] interface IGifSmileyCtrl
+
+struct __declspec(uuid("58b32d03-1bd2-4840-992e-9ae799fd4ade"))
+ITooltipData : IUnknown
+{
+ //
+ // Raw methods provided by interface
+ //
+
+ virtual HRESULT __stdcall SetTooltip (
+ /*[in]*/ BSTR bstrHint ) = 0;
+ virtual HRESULT __stdcall GetTooltip (
+ /*[out,retval]*/ BSTR * bstrHint ) = 0;
+};
+
+struct __declspec(uuid("cb64102b-8ce4-4a55-b050-131c435a3a3f"))
+IGifSmileyCtrl : IUnknown
+{
+ //
+ // Raw methods provided by interface
+ //
+
+ virtual HRESULT __stdcall put_BackColor (
+ /*[in]*/ OLE_COLOR pclr ) = 0;
+ virtual HRESULT __stdcall get_BackColor (
+ /*[out,retval]*/ OLE_COLOR * pclr ) = 0;
+ virtual HRESULT __stdcall get_HWND (
+ /*[out,retval]*/ long * pHWND ) = 0;
+ virtual HRESULT __stdcall LoadFromFile (
+ /*[in]*/ BSTR bstrFileName ) = 0;
+ virtual HRESULT __stdcall LoadFromFileSized (
+ /*[in]*/ BSTR bstrFileName,
+ /*[in]*/ int nHeight ) = 0;
+ virtual HRESULT __stdcall SetHostWindow (
+ /*[in]*/ long hwndHostWindow,
+ /*[in]*/ int nNotyfyMode ) = 0;
+ virtual HRESULT __stdcall ShowHint ( ) = 0;
+};
+
+#pragma pack(pop)
diff --git a/Plugins/emoticons/sdk/m_anismiley.h b/Plugins/emoticons/sdk/m_anismiley.h
new file mode 100644
index 0000000..d839cb3
--- /dev/null
+++ b/Plugins/emoticons/sdk/m_anismiley.h
@@ -0,0 +1,116 @@
+#ifndef m_anismiley_h__
+#define m_anismiley_h__
+
+
+#define IASF_UNICODE 1
+#ifdef UNICODE
+#define IASF_TCHAR IASF_UNICODE
+#else
+#define IASF_TCHAR 0
+#endif
+
+typedef struct _tagINSERTANISMILEY
+{
+ size_t cbSize;
+ HWND hWnd;
+ union
+ {
+ char * szFilename;
+ wchar_t * wcFilename;
+ TCHAR * tcsFilename;
+ };
+ COLORREF dwBackColor;
+ int nHeight;
+ DWORD dwFlags;
+ union
+ {
+ char * szText;
+ wchar_t * wcText;
+ TCHAR * tcsText;
+ };
+}INSERTANISMILEY;
+#define MS_INSERTANISMILEY "mAnimator/InsertSmiley"
+
+#if defined ServiceExists && defined CallService && !defined InsertAnimatedSmiley
+
+#ifdef _cplusplus
+extern "C" {
+#endif
+static BOOL InsertAnimatedSmiley(HWND _hwnd, TCHAR * _szFilename, COLORREF _dwBack, int _nHeight, TCHAR * _szText)
+ {
+ static int bServiceExists=-1;
+ INSERTANISMILEY ias={0};
+ if (bServiceExists==-1)
+ bServiceExists=ServiceExists(MS_INSERTANISMILEY);
+ if (!bServiceExists) return FALSE;
+ ias.cbSize=sizeof(INSERTANISMILEY);
+ ias.hWnd=_hwnd;
+ ias.tcsFilename=_szFilename;
+ ias.dwFlags=IASF_TCHAR;
+ ias.nHeight=_nHeight;
+ ias.dwBackColor=_dwBack;
+ ias.tcsText=_szText;
+ return (BOOL) CallService(MS_INSERTANISMILEY,(WPARAM)&ias, 0);
+ };
+#ifdef _cplusplus
+};
+#endif
+#endif // defined ServiceExists && defined CallService
+
+
+
+/**
+ NM_FIREVIEWCHANGE is WM_NOTIFY Message for notify parent of host window about smiley are going to be repaint
+
+ The proposed action is next: Owner of RichEdit windows received NM_FIREVIEWCHANGE through WM_NOTIFY
+ twice first time before painting|invalidating (FVCN_PREFIRE) and second time - after (FVCN_POSTFIRE).
+ The Owner window may change any values of received FVCNDATA_NMHDR structure in order to raise needed action.
+ For example it may substitute FVCA_INVALIDATE to FVCA_CUSTOMDRAW event to force painting on self offscreen context.
+
+ It can be:
+ FVCA_CUSTOMDRAW - in this case you need to provide valid HDC to draw on and valid RECT of smiley
+ FVCA_INVALIDATE - to invalidate specified rect of window
+ FVCA_NONE - skip any action. But be aware - animation will be stopped till next repainting of smiley.
+ FVCA_SENDVIEWCHANGE - to notify richedit ole about object changed. Be aware Richedit will fully reconstruct itself
+
+ Another point is moment of received smiley rect - it is only valid if FVCA_DRAW is initially set,
+ and it is PROBABLY valid if FVCA_INVALIDATE is set. And it most probably invalid in case of FVCA_SENDVIEWCHANGE.
+ The smiley position is relative last full paint HDC. Usually it is relative to top-left corner of host
+ richedit (NOT it client area) in windows coordinates.
+
+*/
+
+// Type of Event one of
+#define FVCN_PREFIRE 1
+#define FVCN_POSTFIRE 2
+
+// Action of event are going to be done
+#define FVCA_NONE 0
+#define FVCA_DRAW 1 // do not modify hdc in case of _DRAW, Use _CUSTOMDRAW
+#define FVCA_CUSTOMDRAW 2
+#define FVCA_INVALIDATE 3
+#define FVCA_SENDVIEWCHANGE 4
+#define FVCA_SKIPDRAW 5
+
+// Extended NMHDR structure for WM_NOTIFY
+typedef struct
+{
+ //NMHDR structure
+ HWND hwndFrom; // Window of smiley host
+ UINT idFrom; // ignored
+ UINT code; // NM_FIREVIEWCHANGE
+
+ size_t cbSize;
+ BYTE bEvent; // FVCN_ value - pre- or post- painting
+ BYTE bAction; // FVCA_ keys
+ HDC hDC; // Canvas to draw on
+ RECT rcRect; // Valid/should be in case of FVCA_DRAW
+ COLORREF clrBackground; // color to fill background if fTransparent is not set
+ BOOL fTransparent; // if need to fill back color
+ LPARAM lParam; // used by host window PreFire and PostFire event
+} FVCNDATA_NMHDR;
+
+// Code of WM_NOTIFY message (code)
+#define NM_FIREVIEWCHANGE NM_FIRST+1;
+
+#endif // m_anismiley_h__ \ No newline at end of file
diff --git a/Plugins/emoticons/sdk/m_customsmileys.h b/Plugins/emoticons/sdk/m_customsmileys.h
new file mode 100644
index 0000000..afe99bd
--- /dev/null
+++ b/Plugins/emoticons/sdk/m_customsmileys.h
@@ -0,0 +1,52 @@
+#ifndef __M_CUSTOMSMILEYS_H__
+# define __M_CUSTOMSMILEYS_H__
+
+
+#define CUSTOMSMILEY_STATE_RECEIVED 1
+#define CUSTOMSMILEY_STATE_DOWNLOADED 2
+#define CUSTOMSMILEY_UNICODE 0x100
+
+#ifdef UNICODE
+# define CUSTOMSMILEY_TCHAR CUSTOMSMILEY_UNICODE
+#else
+# define CUSTOMSMILEY_TCHAR 0
+#endif
+
+typedef struct
+{
+ int cbSize;
+ HANDLE hContact;
+ union {
+ const char *pszText; // Valid only during the notification. Optional if CUSTOMSMILEY_STATE_DOWNLOADED
+ const TCHAR *ptszText; // Valid only during the notification. Optional if CUSTOMSMILEY_STATE_DOWNLOADED
+ const WCHAR *pwszText; // Valid only during the notification. Optional if CUSTOMSMILEY_STATE_DOWNLOADED
+ };
+ const char *pszFilename; // Valid only during the notification
+ int flags; // One of CUSTOMSMILEY_STATE_*
+ BOOL download; // "Return" value. Someone have to change it to TRUE for it to be downloaded
+} CUSTOMSMILEY;
+
+
+// Fired when a custom smiley is received from a contact.
+// This can is fired 2 times:
+// 1. When received the text, with flag CUSTOMSMILEY_STATE_RECEIVED. If someone hooks this message and
+// wants the custom smiley, it has to change the download field to TRUE
+// 2. If needed, when the image was downloaded, with flag CUSTOMSMILEY_STATE_DOWNLOADED
+// If the protocol receives the smiley text and image at the same time, it can fire it only once, with
+// flag (CUSTOMSMILEY_STATE_RECEIVED | CUSTOMSMILEY_STATE_DOWNLOADED)
+//
+// wParam = 0
+// lParam = CUSTOMSMILEY *
+#define ME_CUSTOMSMILEY_RECEIVED "/CustomSmileyReceived"
+
+
+
+
+
+
+
+
+
+
+
+#endif __M_CUSTOMSMILEYS_H__
diff --git a/Plugins/emoticons/sdk/m_folders.h b/Plugins/emoticons/sdk/m_folders.h
new file mode 100644
index 0000000..c232410
--- /dev/null
+++ b/Plugins/emoticons/sdk/m_folders.h
@@ -0,0 +1,205 @@
+/*
+Custom profile folders plugin for Miranda IM
+
+Copyright © 2005 Cristian Libotean
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_CUSTOM_FOLDERS_H
+#define M_CUSTOM_FOLDERS_H
+
+#define FOLDERS_API 501 //dunno why it's here but it is :)
+
+#define PROFILE_PATH "%profile_path%"
+#define CURRENT_PROFILE "%current_profile%"
+#define MIRANDA_PATH "%miranda_path%"
+#define PLUGINS_PATH "%miranda_path%" "\\plugins"
+
+#define TO_WIDE(x) L ## x
+
+#define PROFILE_PATHW L"%profile_path%"
+#define CURRENT_PROFILEW L"%current_profile%"
+#define MIRANDA_PATHW L"%miranda_path%"
+
+#define FOLDER_AVATARS PROFILE_PATH "\\" CURRENT_PROFILE "\\avatars"
+#define FOLDER_VCARDS PROFILE_PATH "\\" CURRENT_PROFILE "\\vcards"
+#define FOLDER_LOGS PROFILE_PATH "\\" CURRENT_PROFILE "\\logs"
+#define FOLDER_RECEIVED_FILES PROFILE_PATH "\\" CURRENT_PROFILE "\\received files"
+#define FOLDER_DOCS MIRANDA_PATH "\\" "docs"
+
+#define FOLDER_CONFIG PLUGINS_PATH "\\" "config"
+
+#define FOLDER_SCRIPTS MIRANDA_PATH "\\" "scripts"
+
+#define FOLDER_UPDATES MIRANDA_PATH "\\" "updates"
+
+#define FOLDER_CUSTOMIZE MIRANDA_PATH "\\" "customize"
+#define FOLDER_CUSTOMIZE_SOUNDS FOLDER_CUSTOMIZE "\\sounds"
+#define FOLDER_CUSTOMIZE_ICONS FOLDER_CUSTOMIZE "\\icons"
+#define FOLDER_CUSTOMIZE_SMILEYS FOLDER_CUSTOMIZE "\\smileys"
+#define FOLDER_CUSTOMIZE_SKINS FOLDER_CUSTOMIZE "\\skins"
+#define FOLDER_CUSTOMIZE_THEMES FOLDER_CUSTOMIZE "\\themes"
+
+
+#define FOLDERS_NAME_MAX_SIZE 64 //maximum name and section size
+
+#define FF_UNICODE 0x00000001
+
+typedef struct{
+ int cbSize; //size of struct
+ char szSection[FOLDERS_NAME_MAX_SIZE]; //section name, if it doesn't exist it will be created otherwise it will just add this entry to it
+ char szName[FOLDERS_NAME_MAX_SIZE]; //entry name - will be shown in options
+ union{
+ const char *szFormat; //default string format. Fallback string in case there's no entry in the database for this folder. This should be the initial value for the path, users will be able to change it later.
+ const wchar_t *szFormatW; //String is dup()'d so you can free it later. If you set the unicode string don't forget to set the flag accordingly.
+ const TCHAR *szFormatT;
+ };
+ DWORD flags; //FF_* flags
+} FOLDERSDATA;
+
+/*Folders/Register/Path service
+ wParam - not used, must be 0
+ lParam - (LPARAM) (const FOLDERDATA *) - Data structure filled with
+ the necessary information.
+ Returns a handle to the registered path or 0 on error.
+ You need to use this to call the other services.
+*/
+#define MS_FOLDERS_REGISTER_PATH "Folders/Register/Path"
+
+/*Folders/Get/PathSize service
+ wParam - (WPARAM) (int) - handle to registered path
+ lParam - (LPARAM) (int *) - pointer to the variable that receives the size of the path
+ string (not including the null character). Depending on the flags set when creating the path
+ it will either call strlen() or wcslen() to get the length of the string.
+ Returns the size of the buffer.
+*/
+#define MS_FOLDERS_GET_SIZE "Folders/Get/PathSize"
+
+typedef struct{
+ int cbSize;
+ int nMaxPathSize; //maximum size of buffer. This represents the number of characters that can be copied to it (so for unicode strings you don't send the number of bytes but the length of the string).
+ union{
+ char *szPath; //pointer to the buffer that receives the path without the last "\\"
+ wchar_t *szPathW; //unicode version of the buffer.
+ TCHAR *szPathT;
+ };
+} FOLDERSGETDATA;
+
+/*Folders/Get/Path service
+ wParam - (WPARAM) (int) - handle to registered path
+ lParam - (LPARAM) (FOLDERSGETDATA *) pointer to a FOLDERSGETDATA that has all the relevant fields filled.
+ Should return 0 on success, or nonzero otherwise.
+*/
+#define MS_FOLDERS_GET_PATH "Folders/Get/Path"
+
+typedef struct{
+ int cbSize;
+ union{
+ char **szPath; //address of a string variable (char *) or (wchar_t*) where the path should be stored (the last \ won't be copied).
+ wchar_t **szPathW; //unicode version of string.
+ TCHAR **szPathT;
+ };
+} FOLDERSGETALLOCDATA;
+
+/*Folders/GetRelativePath/Alloc service
+ wParam - (WPARAM) (int) - Handle to registered path
+ lParam - (LPARAM) (FOLDERSALLOCDATA *) data
+ This service is the same as MS_FOLDERS_GET_PATH with the difference that this service
+ allocates the needed space for the buffer. It uses miranda's memory functions for that and you need
+ to use those to free the resulting buffer.
+ Should return 0 on success, or nonzero otherwise. Currently it only returns 0.
+*/
+#define MS_FOLDERS_GET_PATH_ALLOC "Folders/Get/Path/Alloc"
+
+
+/*Folders/On/Path/Changed
+ wParam - (WPARAM) 0
+ lParam - (LPARAM) 0
+ Triggered when the folders change, you should reget the paths you registered.
+*/
+#define ME_FOLDERS_PATH_CHANGED "Folders/On/Path/Changed"
+
+#ifndef FOLDERS_NO_HELPER_FUNCTIONS
+//#include "../../../include/newpluginapi.h"
+
+__inline static int FoldersRegisterCustomPath(const char *section, const char *name, const char *defaultPath)
+{
+ FOLDERSDATA fd = {0};
+ if (!ServiceExists(MS_FOLDERS_REGISTER_PATH)) return 1;
+ fd.cbSize = sizeof(FOLDERSDATA);
+ strncpy(fd.szSection, section, FOLDERS_NAME_MAX_SIZE);
+ fd.szSection[FOLDERS_NAME_MAX_SIZE - 1] = '\0';
+ strncpy(fd.szName, name, FOLDERS_NAME_MAX_SIZE);
+ fd.szName[FOLDERS_NAME_MAX_SIZE - 1] = '\0';
+ fd.szFormat = defaultPath;
+ return CallService(MS_FOLDERS_REGISTER_PATH, 0, (LPARAM) &fd);
+}
+
+__inline static int FoldersRegisterCustomPathW(const char *section, const char *name, const wchar_t *defaultPathW)
+{
+ FOLDERSDATA fd = {0};
+ if (!ServiceExists(MS_FOLDERS_REGISTER_PATH)) return 1;
+ fd.cbSize = sizeof(FOLDERSDATA);
+ strncpy(fd.szSection, section, FOLDERS_NAME_MAX_SIZE);
+ fd.szSection[FOLDERS_NAME_MAX_SIZE - 1] = '\0'; //make sure it's NULL terminated
+ strncpy(fd.szName, name, FOLDERS_NAME_MAX_SIZE);
+ fd.szName[FOLDERS_NAME_MAX_SIZE - 1] = '\0'; //make sure it's NULL terminated
+ fd.szFormatW = defaultPathW;
+ fd.flags = FF_UNICODE;
+ return CallService(MS_FOLDERS_REGISTER_PATH, 0, (LPARAM) &fd);
+}
+
+__inline static int FoldersGetCustomPath(HANDLE hFolderEntry, char *path, const int size, char *notFound)
+{
+ FOLDERSGETDATA fgd = {0};
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = size;
+ fgd.szPath = path;
+ int res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ strncpy(path, notFound, size);
+ path[size - 1] = '\0'; //make sure it's NULL terminated
+ }
+ return res;
+}
+
+__inline static int FoldersGetCustomPathW(HANDLE hFolderEntry, wchar_t *pathW, const int count, wchar_t *notFoundW)
+{
+ FOLDERSGETDATA fgd = {0};
+ fgd.cbSize = sizeof(FOLDERSGETDATA);
+ fgd.nMaxPathSize = count;
+ fgd.szPathW = pathW;
+ int res = CallService(MS_FOLDERS_GET_PATH, (WPARAM) hFolderEntry, (LPARAM) &fgd);
+ if (res)
+ {
+ wcsncpy(pathW, notFoundW, count);
+ pathW[count - 1] = '\0';
+ }
+ return res;
+}
+
+# ifdef _UNICODE
+# define FoldersGetCustomPathT FoldersGetCustomPathW
+# define FoldersRegisterCustomPathT FoldersRegisterCustomPathW
+#else
+# define FoldersGetCustomPathT FoldersGetCustomPath
+# define FoldersRegisterCustomPathT FoldersRegisterCustomPath
+#endif
+
+#endif
+
+#endif //M_CUSTOM_FOLDERS_H \ No newline at end of file
diff --git a/Plugins/emoticons/sdk/m_metacontacts.h b/Plugins/emoticons/sdk/m_metacontacts.h
new file mode 100644
index 0000000..1da12b9
--- /dev/null
+++ b/Plugins/emoticons/sdk/m_metacontacts.h
@@ -0,0 +1,162 @@
+/*
+
+Miranda IM: the free IM client for Microsoft* Windows*
+
+Copyright © 2004 Universite Louis PASTEUR, STRASBOURG.
+Copyright © 2004 Scott Ellis (www.scottellis.com.au mail@scottellis.com.au)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#ifndef M_METACONTACTS_H__
+#define M_METACONTACTS_H__ 1
+
+//get the handle for a contact's parent metacontact
+//wParam=(HANDLE)hSubContact
+//lParam=0
+//returns a handle to the parent metacontact, or null if this contact is not a subcontact
+#define MS_MC_GETMETACONTACT "MetaContacts/GetMeta"
+
+//gets the handle for the default contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a handle to the default contact, or null on failure
+#define MS_MC_GETDEFAULTCONTACT "MetaContacts/GetDefault"
+
+//gets the contact number for the default contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a DWORD contact number, or -1 on failure
+#define MS_MC_GETDEFAULTCONTACTNUM "MetaContacts/GetDefaultNum"
+
+//gets the handle for the 'most online' contact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a handle to the 'most online' contact
+#define MS_MC_GETMOSTONLINECONTACT "MetaContacts/GetMostOnline"
+
+//gets the number of subcontacts for a metacontact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns a DWORD representing the number of subcontacts for the given metacontact
+#define MS_MC_GETNUMCONTACTS "MetaContacts/GetNumContacts"
+
+//gets the handle of a subcontact, using the subcontact's number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns a handle to the specified subcontact
+#define MS_MC_GETSUBCONTACT "MetaContacts/GetSubContact"
+
+//sets the default contact, using the subcontact's contact number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns 0 on success
+#define MS_MC_SETDEFAULTCONTACTNUM "MetaContacts/SetDefault"
+
+//sets the default contact, using the subcontact's handle
+//wParam=(HANDLE)hMetaContact
+//lParam=(HANDLE)hSubcontact
+//returns 0 on success
+#define MS_MC_SETDEFAULTCONTACT "MetaContacts/SetDefaultByHandle"
+
+//forces the metacontact to send using a specific subcontact, using the subcontact's contact number
+//wParam=(HANDLE)hMetaContact
+//lParam=(DWORD)contact number
+//returns 0 on success
+#define MS_MC_FORCESENDCONTACTNUM "MetaContacts/ForceSendContact"
+
+//forces the metacontact to send using a specific subcontact, using the subcontact's handle
+//wParam=(HANDLE)hMetaContact
+//lParam=(HANDLE)hSubcontact
+//returns 0 on success (will fail if 'force default' is in effect)
+#define MS_MC_FORCESENDCONTACT "MetaContacts/ForceSendContactByHandle"
+
+//'unforces' the metacontact to send using a specific subcontact
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns 0 on success (will fail if 'force default' is in effect)
+#define MS_MC_UNFORCESENDCONTACT "MetaContacts/UnforceSendContact"
+
+//'forces' or 'unforces' (i.e. toggles) the metacontact to send using it's default contact
+// overrides (and clears) 'force send' above, and will even force use of offline contacts
+// will send ME_MC_FORCESEND or ME_MC_UNFORCESEND event
+//wParam=(HANDLE)hMetaContact
+//lParam=0
+//returns 1(true) or 0(false) representing new state of 'force default'
+#define MS_MC_FORCEDEFAULT "MetaContacts/ForceSendDefault"
+
+// method to get state of 'force' for a metacontact
+// wParam=(HANDLE)hMetaContact
+// lParam= (DWORD)&contact_number or NULL
+//
+// if lparam supplied, the contact_number of the contatct 'in force' will be copied to the address it points to,
+// or if none is in force, the value (DWORD)-1 will be copied
+// (v0.8.0.8+ returns 1 if 'force default' is true with *lParam == default contact number, else returns 0 with *lParam as above)
+#define MS_MC_GETFORCESTATE "MetaContacts/GetForceState"
+
+// fired when a metacontact's default contact changes (fired upon creation of metacontact also, when default is initially set)
+// wParam=(HANDLE)hMetaContact
+// lParam=(HANDLE)hDefaultContact
+#define ME_MC_DEFAULTTCHANGED "MetaContacts/DefaultChanged"
+
+// fired when a metacontact's subcontacts change (fired upon creation of metacontact, when contacts are added or removed, and when
+// contacts are reordered) - a signal to re-read metacontact data
+// wParam=(HANDLE)hMetaContact
+// lParam=0
+#define ME_MC_SUBCONTACTSCHANGED "MetaContacts/SubcontactsChanged"
+
+// fired when a metacontact is forced to send using a specific subcontact
+// wParam=(HANDLE)hMetaContact
+// lParam=(HANDLE)hForceContact
+#define ME_MC_FORCESEND "MetaContacts/ForceSend"
+
+// fired when a metacontact is 'unforced' to send using a specific subcontact
+// wParam=(HANDLE)hMetaContact
+// lParam=0
+#define ME_MC_UNFORCESEND "MetaContacts/UnforceSend"
+
+// method to get protocol name - used to be sure you're dealing with a "real" metacontacts plugin :)
+// wParam=lParam=0
+#define MS_MC_GETPROTOCOLNAME "MetaContacts/GetProtoName"
+
+
+// added 0.9.5.0 (22/3/05)
+// wParam=(HANDLE)hContact
+// lParam=0
+// convert a given contact into a metacontact
+#define MS_MC_CONVERTTOMETA "MetaContacts/ConvertToMetacontact"
+
+// added 0.9.5.0 (22/3/05)
+// wParam=(HANDLE)hContact
+// lParam=(HANDLE)hMeta
+// add an existing contact to a metacontact
+#define MS_MC_ADDTOMETA "MetaContacts/AddToMetacontact"
+
+// added 0.9.5.0 (22/3/05)
+// wParam=0
+// lParam=(HANDLE)hContact
+// remove a contact from a metacontact
+#define MS_MC_REMOVEFROMMETA "MetaContacts/RemoveFromMetacontact"
+
+
+// added 0.9.13.2 (6/10/05)
+// wParam=(BOOL)disable
+// lParam=0
+// enable/disable the 'hidden group hack' - for clists that support subcontact hiding using 'IsSubcontact' setting
+// should be called once in the clist 'onmodulesloaded' event handler (which, since it's loaded after the db, will be called
+// before the metacontact onmodulesloaded handler where the subcontact hiding is usually done)
+#define MS_MC_DISABLEHIDDENGROUP "MetaContacts/DisableHiddenGroup"
+
+#endif
diff --git a/Plugins/emoticons/sdk/m_smileyadd.h b/Plugins/emoticons/sdk/m_smileyadd.h
new file mode 100644
index 0000000..18e2462
--- /dev/null
+++ b/Plugins/emoticons/sdk/m_smileyadd.h
@@ -0,0 +1,182 @@
+/*
+Miranda SmileyAdd Plugin
+Plugin support header file
+Copyright (C) 2004-2007 Boris Krasnovskiy, portions by Rein-Peter de Boer
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+#define SAFLRE_INSERTEMF 2 // insert smiley as EMF into RichEdit, otherwise bitmap inserted
+ // this flag allows "true" transparency
+
+typedef struct
+{
+ unsigned cbSize; //size of the structure
+ HWND hwndRichEditControl; //handle to the rich edit control
+ CHARRANGE* rangeToReplace; //same meaning as for normal Richedit use (NULL = replaceall)
+ const char* Protocolname; //protocol to use... if you have defined a protocol, u can
+ //use your own protocol name. SmileyAdd will automatically
+ //select the smileypack that is defined for your protocol.
+ //Or, use "Standard" for standard smiley set. Or "ICQ", "MSN"
+ //if you prefer those icons.
+ //If not found or NULL, "Standard" will be used
+ unsigned flags; //Flags (SAFLRE_*) that define the behaivior
+ BOOL disableRedraw; //Parameter have been depricated, have no effect on operation
+ HANDLE hContact; //Contact handle
+} SMADD_RICHEDIT3;
+
+//Replace smileys in a rich edit control...
+//wParam = (WPARAM) 0; not used
+//lParam = (LPARAM) (SMADD_RICHEDIT3*) &smre; //pointer to SMADD_RICHEDIT3
+//return: TRUE if API succeeded (all parameters were valid) , FALSE if not.
+#define MS_SMILEYADD_REPLACESMILEYS "SmileyAdd/ReplaceSmileys"
+
+
+typedef struct
+{
+ unsigned cbSize; //size of the structure
+ char* Protocolname; //protocol to use... if you have defined a protocol, you can
+ //use your own protocol name. Smiley add will automatically
+ //select the smileypack that is defined for your protocol.
+ //Or, use "Standard" for standard smiley set. Or "ICQ", "MSN"
+ //if you prefer those icons.
+ //If not found or NULL: "Standard" will be used
+ int xPosition; //Postition to place the selectwindow
+ int yPosition; // "
+ int Direction; //Direction (i.e. size upwards/downwards/etc) of the window 0, 1, 2, 3
+
+ HWND hwndTarget; //Window, where to send the message when smiley is selected.
+ UINT targetMessage; //Target message, to be sent.
+ LPARAM targetWParam; //Target WParam to be sent (LParam will be char* to select smiley)
+ //see the example file.
+ HWND hwndParent; //Parent window for smiley dialog
+ HANDLE hContact; //Contact handle
+} SMADD_SHOWSEL3;
+
+//Show smiley selection window
+//wParam = (WPARAM) 0; not used
+//lParam = (LPARAM) (SMADD_SHOWSEL3*) &smre; //pointer to SMADD_SHOWSEL3
+//return: TRUE if API succeeded (all parameters were valid) , FALSE if not.
+#define MS_SMILEYADD_SHOWSELECTION "SmileyAdd/ShowSmileySelection"
+
+
+typedef struct
+{
+ unsigned cbSize; //size of the structure
+ char* Protocolname; // " "
+ HICON ButtonIcon; //RETURN VALUE: this is filled with the icon handle
+ //of the smiley that can be used on the button
+ //if used with GETINFO2 handle must be destroyed by user!
+ //NULL if the buttonicon is not defined...
+ int NumberOfVisibleSmileys; //Number of visible smileys defined.
+ int NumberOfSmileys; //Number of total smileys defined
+ HANDLE hContact; //Contact handle
+} SMADD_INFO2;
+
+//get button smiley icon
+//wParam = (WPARAM) 0; not used
+//lParam = (LPARAM) (SMADD_INFO2*) &smgi; //pointer to SMADD_INFO2
+//return: TRUE if API succeeded (all parameters were valid) , FALSE if not.
+#define MS_SMILEYADD_GETINFO2 "SmileyAdd/GetInfo2"
+
+// Event notifies that SmileyAdd options have changed
+// Message dialogs usually need to redraw it's content on reception of this event
+//wParam = Contact handle which options have changed, NULL if global options changed
+//lParam = (LPARAM) 0; not used
+#define ME_SMILEYADD_OPTIONSCHANGED "SmileyAdd/OptionsChanged"
+
+#define SAFL_PATH 1 // provide smiley file path, icon otherwise
+#define SAFL_UNICODE 2 // string fields in OPTIONSDIALOGPAGE are WCHAR*
+
+#if defined _UNICODE || defined UNICODE
+ #define SAFL_TCHAR SAFL_UNICODE
+#else
+ #define SAFL_TCHAR 0
+#endif
+
+typedef struct
+{
+ unsigned cbSize; //size of the structure
+ const char* Protocolname; //protocol to use... if you have defined a protocol, u can
+ //use your own protocol name. Smiley add wil automatically
+ //select the smileypack that is defined for your protocol.
+ //Or, use "Standard" for standard smiley set. Or "ICQ", "MSN"
+ //if you prefer those icons.
+ //If not found or NULL: "Standard" will be used
+ union {
+ TCHAR* str; //String to parse
+ char* astr;
+ wchar_t* wstr;
+ };
+ unsigned flag; //One of the SAFL_ flags specifies parsing requirements
+ //This parameter should be filled by the user
+
+ unsigned numSmileys; //Number of Smileys found, this parameter filled by SmileyAdd
+ unsigned oflag; //One of the SAFL_ flags specifies content of the parse results
+ //this parameter filled by SmileyAdd
+ HANDLE hContact; //Contact handle
+} SMADD_BATCHPARSE2;
+
+typedef struct
+{
+ unsigned startChar; //Starting smiley character
+ //Because of iterative nature of the API caller should set this
+ //parameter to correct value
+ unsigned size; //Number of characters in smiley (0 if not found)
+ //Because of iterative nature of the API caller should set this
+ //parameter to correct value
+ union {
+ const TCHAR* filepath;
+ const char* afilepath;
+ const wchar_t* wfilepath;
+ HICON hIcon; //User responsible for destroying icon handle
+ };
+} SMADD_BATCHPARSERES;
+
+//find all smileys in text, API parses the provided text and returns all smileys found
+//wParam = (WPARAM) 0; not used
+//lParam = (LPARAM) (SMADD_BATCHPARSE2*) &smgp; //pointer to SMADD_BATCHPARSE2
+//function returns pointer to array SMADD_BATCHPARSERES records for each smiley found
+//if no smileys found NULL is returned
+//if non NULL value returned pointer must be freed with MS_SMILEYADD_BATCHFREE API
+#define MS_SMILEYADD_BATCHPARSE "SmileyAdd/BatchParse"
+
+//Free memory allocated by MS_SMILEYADD_BATCHPARSE
+//wParam = (WPARAM) 0; not used
+//lParam = (LPARAM) (SMADD_BATCHPARSERES*) &smgp; //pointer to SMADD_BATCHPARSERES
+#define MS_SMILEYADD_BATCHFREE "SmileyAdd/BatchFree"
+
+typedef struct
+{
+ unsigned cbSize; //size of the structure
+ char* name; //smiley category name for reference
+ char* dispname; //smiley category name for display
+} SMADD_REGCAT;
+
+//Register smiley category
+//wParam = (WPARAM) 0; not used
+//lParam = (LPARAM) (SMADD_REGCAT*) &smgp; pointer to SMADD_REGCAT
+#define MS_SMILEYADD_REGISTERCATEGORY "SmileyAdd/RegisterCategory"
+
+//Register smiley category
+//wParam = (WPARAM) 0; not used
+//lParam = (LPARAM) Pointer to protocol name or NULL for all;
+#define MS_SMILEYADD_RELOAD "SmileyAdd/Reload"
+
+#ifndef MIID_SMILEY
+// {E03C71B2-6DEE-467e-A4F0-DD516745876A}
+#define MIID_SMILEY { 0xe03c71b2, 0x6dee, 0x467e, { 0xa4, 0xf0, 0xdd, 0x51, 0x67, 0x45, 0x87, 0x6a } }
+#endif
diff --git a/Plugins/emoticons/sdk/m_updater.h b/Plugins/emoticons/sdk/m_updater.h
new file mode 100644
index 0000000..371b743
--- /dev/null
+++ b/Plugins/emoticons/sdk/m_updater.h
@@ -0,0 +1,146 @@
+#ifndef _M_UPDATER_H
+#define _M_UPDATER_H
+
+// NOTES:
+// - For langpack updates, include a string of the following format in the langpack text file:
+// ";FLID: <file listing name> <version>"
+// version must be four numbers seperated by '.', in the range 0-255 inclusive
+// - Updater will disable plugins that are downloaded but were not active prior to the update (this is so that, if an archive contains e.g. ansi and
+// unicode versions, the correct plugin will be the only one active after the new version is installed)...so if you add a support plugin, you may need
+// to install an ini file to make the plugin activate when miranda restarts after the update
+// - Updater will replace all dlls that have the same internal shortName as a downloaded update dll (this is so that msn1.dll and msn2.dll, for example,
+// will both be updated) - so if you have a unicode and a non-unicode version of a plugin in your archive, you should make the internal names different (which will break automatic
+// updates from the file listing if there is only one file listing entry for both versions, unless you use the 'MS_UPDATE_REGISTER' service below)
+// - Updater will install all files in the root of the archive into the plugins folder, except for langpack files that contain the FLID string which go into the root folder (same
+// folder as miranda32.exe)...all folders in the archive will also be copied to miranda's root folder, and their contents transferred into the new folders. The only exception is a
+// special folder called 'root_files' - if there is a folder by that name in the archive, it's contents will also be copied into miranda's root folder - this is intended to be used
+// to install additional dlls etc that a plugin may require)
+
+// if you set Update.szUpdateURL to the following value when registering, as well as setting your beta site and version data,
+// Updater will ignore szVersionURL and pbVersionPrefix, and attempt to find the file listing URL's from the backend XML data.
+// for this to work, the plugin name in pluginInfo.shortName must match the file listing exactly (except for case)
+#define UPDATER_AUTOREGISTER "UpdaterAUTOREGISTER"
+// Updater will also use the backend xml data if you provide URL's that reference the miranda file listing for updates (so you can use that method
+// if e.g. your plugin shortName does not match the file listing) - it will grab the file listing id from the end of these URLs
+
+typedef struct Update_tag {
+ int cbSize;
+ char *szComponentName; // component name as it will appear in the UI (will be translated before displaying)
+
+ char *szVersionURL; // URL where the current version can be found (NULL to disable)
+ BYTE *pbVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ // (note that this URL could point at a binary file - dunno why, but it could :)
+ int cpbVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szUpdateURL; // URL where dll/zip is located
+ // set to UPDATER_AUTOREGISTER if you want Updater to find the file listing URLs (ensure plugin shortName matches file listing!)
+
+ char *szBetaVersionURL; // URL where the beta version can be found (NULL to disable betas)
+ BYTE *pbBetaVersionPrefix; // bytes occuring in VersionURL before the version, used to locate the version information within the URL data
+ int cpbBetaVersionPrefix; // number of bytes pointed to by pbVersionPrefix
+ char *szBetaUpdateURL; // URL where dll/zip is located
+
+ BYTE *pbVersion; // bytes of current version, used for comparison with those in VersionURL
+ int cpbVersion; // number of bytes pointed to by pbVersion
+
+ char *szBetaChangelogURL; // url for displaying changelog for beta versions
+} Update;
+
+// register a comonent with Updater
+//
+// wparam = 0
+// lparam = (LPARAM)&Update
+#define MS_UPDATE_REGISTER "Update/Register"
+
+// utility functions to create a version string from a DWORD or from pluginInfo
+// point buf at a buffer at least 16 chars wide - but note the version string returned may be shorter
+//
+__inline static char *CreateVersionString(DWORD version, char *buf) {
+ mir_snprintf(buf, 16, "%d.%d.%d.%d", (version >> 24) & 0xFF, (version >> 16) & 0xFF, (version >> 8) & 0xFF, version & 0xFF);
+ return buf;
+}
+
+__inline static char *CreateVersionStringPlugin(PLUGININFO *pluginInfo, char *buf) {
+ return CreateVersionString(pluginInfo->version, buf);
+}
+
+
+// register the 'easy' way - use this method if you have no beta URL and the plugin is on the miranda file listing
+// NOTE: the plugin version string on the file listing must be the string version of the version in pluginInfo (i.e. 0.0.0.1,
+// four numbers between 0 and 255 inclusivem, so no letters, brackets, etc.)
+//
+// wParam = (int)fileID - this is the file ID from the file listing (i.e. the number at the end of the download link)
+// lParam = (PLUGININFO*)&pluginInfo
+#define MS_UPDATE_REGISTERFL "Update/RegisterFL"
+
+// this function can be used to 'unregister' components - useful for plugins that register non-plugin/langpack components and
+// may need to change those components on the fly
+// lParam = (char *)szComponentName
+#define MS_UPDATE_UNREGISTER "Update/Unregister"
+
+// this event is fired when the startup process is complete, but NOT if a restart is imminent
+// it is designed for status managment plugins to use as a trigger for beggining their own startup process
+// wParam = lParam = 0 (unused)
+// (added in version 0.1.6.0)
+#define ME_UPDATE_STARTUPDONE "Update/StartupDone"
+
+// this service can be used to enable/disable Updater's global status control
+// it can be called from the StartupDone event handler
+// wParam = (BOOL)enable
+// lParam = 0
+// (added in version 0.1.6.0)
+#define MS_UPDATE_ENABLESTATUSCONTROL "Update/EnableStatusControl"
+
+// An description of usage of the above service and event:
+// Say you are a status control plugin that normally sets protocol or global statuses in your ModulesLoaded event handler.
+// In order to make yourself 'Updater compatible', you would move the status control code from ModulesLoaded to another function,
+// say DoStartup. Then, in ModulesLoaded you would check for the existence of the MS_UPDATE_ENABLESTATUSCONTROL service.
+// If it does not exist, call DoStartup. If it does exist, hook the ME_UPDATE_STARTUPDONE event and call DoStartup from there. You may
+// also wish to call MS_UPDATE_ENABLESTATUSCONTROL with wParam == FALSE at this time, to disable Updater's own status control feature.
+
+// this service can be used to determine whether updates are possible for a component with the given name
+// wParam = 0
+// lParam = (char *)szComponentName
+// returns TRUE if updates are supported, FALSE otherwise
+#define MS_UPDATE_ISUPDATESUPPORTED "Update/IsUpdateSupported"
+
+#endif
+
+
+/////////////// Usage Example ///////////////
+
+#ifdef EXAMPLE_CODE
+
+// you need to #include "m_updater.h" and HookEvent(ME_SYSTEM_MODULESLOADED, OnModulesLoaded) in your Load function...
+
+int OnModulesLoaded(WPARAM wParam, LPARAM lParam) {
+
+ Update update = {0}; // for c you'd use memset or ZeroMemory...
+ char szVersion[16];
+
+ update.cbSize = sizeof(Update);
+
+ update.szComponentName = pluginInfo.shortName;
+ update.pbVersion = (BYTE *)CreateVersionString(&pluginInfo, szVersion);
+ update.cpbVersion = strlen((char *)update.pbVersion);
+
+ // these are the three lines that matter - the archive, the page containing the version string, and the text (or data)
+ // before the version that we use to locate it on the page
+ // (note that if the update URL and the version URL point to standard file listing entries, the backend xml
+ // data will be used to check for updates rather than the actual web page - this is not true for beta urls)
+ update.szUpdateURL = "http://scottellis.com.au:81/test/updater.zip";
+ update.szVersionURL = "http://scottellis.com.au:81/test/updater_test.html";
+ update.pbVersionPrefix = (BYTE *)"Updater version ";
+
+ update.cpbVersionPrefix = strlen((char *)update.pbVersionPrefix);
+
+ // do the same for the beta versions of the above struct members if you wish to allow beta updates from another URL
+
+ CallService(MS_UPDATE_REGISTER, 0, (WPARAM)&update);
+
+ // Alternatively, to register a plugin with e.g. file ID 2254 on the file listing...
+ // CallService(MS_UPDATE_REGISTERFL, (WPARAM)2254, (LPARAM)&pluginInfo);
+
+ return 0;
+}
+
+#endif
diff --git a/Plugins/emoticons/sdk/m_variables.h b/Plugins/emoticons/sdk/m_variables.h
new file mode 100644
index 0000000..4bd47c6
--- /dev/null
+++ b/Plugins/emoticons/sdk/m_variables.h
@@ -0,0 +1,720 @@
+/*
+ Variables Plugin for Miranda-IM (www.miranda-im.org)
+ Copyright 2003-2006 P. Boon
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __M_VARS
+#define __M_VARS
+
+#if !defined(_TCHAR_DEFINED)
+#include <tchar.h>
+#endif
+
+#ifndef VARIABLES_NOHELPER
+#include <m_button.h>
+#endif
+
+// --------------------------------------------------------------------------
+// Memory management
+// --------------------------------------------------------------------------
+
+// Release memory that was allocated by the Variables plugin, e.g. returned
+// strings.
+
+#define MS_VARS_FREEMEMORY "Vars/FreeMemory"
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(void *)pntr
+// Pointer to memory that was allocated by the Variables plugin (e.g. a
+// returned string) (can be NULL).
+// lParam = 0
+
+// Return Value:
+// ------------------------
+// Does return 0 on success, nozero otherwise.
+
+// Note: Do only use this service to free memory that was *explicitliy*
+// stated that it should be free with this service.
+
+
+
+#define MS_VARS_GET_MMI "Vars/GetMMI"
+
+// Get Variable's RTL/CRT function poiners to malloc(), free() and
+// realloc().
+
+// Parameters:
+// ------------------------
+// wParam = 0
+// lParam = (LPARAM) &MM_INTERFACE
+// Pointer to a memory manager interface struct (see m_system.h).
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, nozero otherwise
+
+// Note: Works exactly the same as the MS_SYSTEM_GET_MMI service
+// service of m_system.h.
+
+// Helper function for easy using:
+#ifndef VARIABLES_NOHELPER
+__inline static void variables_free(void *pntr) {
+
+ CallService(MS_VARS_FREEMEMORY, (WPARAM)pntr, 0);
+}
+#endif
+
+
+
+// --------------------------------------------------------------------------
+// String formatting
+// --------------------------------------------------------------------------
+
+#define MS_VARS_FORMATSTRING "Vars/FormatString"
+
+#define MS_VARS_FORMATSTRING_EX "Vars/FormatStringEx"
+
+// This service can be used to parse tokens in a text. The tokens will be
+// replaced by their resolved values. A token can either be a field or a
+// function. A field takes no arguments and is represented between
+// %-characters, e.g. "%winampsong%". A function can take any number of
+// arguments and is represented by a ? or !-character followed by the name
+// of the function and a list of arguments, e.g. "?add(1,2)".
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(FORMATINFO *)&fi
+// See below.
+// lParam = 0
+
+// Return Value:
+// ------------------------
+// Returns a pointer to the resolved string or NULL in case of an error.
+
+// Note: The returned pointer needs to be freed using MS_VARS_FREEMEMORY.
+
+typedef struct {
+ int cbSize; // Set this to sizeof(FORMATINFO).
+ int flags; // Flags to use (see FIF_* below).
+ union {
+ char *szFormat; // Text in which the tokens will be replaced (can't be
+ // NULL).
+ WCHAR *wszFormat;
+ TCHAR *tszFormat;
+ };
+ union {
+ char *szExtraText; // Extra, context-specific string (can be NULL) ->
+ // The field "extratext" will be replaced by this
+ // string. (Previously szSource).
+ WCHAR *wszExtraText;
+ TCHAR *tszExtraText;
+ };
+ HANDLE hContact; // Handle to contact (can be NULL) -> The field "subject"
+ // represents this contact.
+ int pCount; // (output) Number of succesful parsed tokens, needs to be set
+ // to 0 before the call
+ int eCount; // (output) Number of failed tokens, needs to be set to 0
+ // before the call
+ union {
+ char **szaTemporaryVars; // Temporary variables valid only in the duration of the format call
+ TCHAR **tszaTemporaryVars; // By pos: [i] is var name, [i + 1] is var value
+ WCHAR **wszaTemporaryVars;
+ };
+ int cbTemporaryVarsSize; // Number of elements in szaTemporaryVars array
+
+} FORMATINFO;
+
+#define FORMATINFOV2_SIZE 28
+
+
+// Possible flags:
+#define FIF_UNICODE 0x01 // Expects and returns unicode text (WCHAR*).
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define FIF_TCHAR FIF_UNICODE // Strings in structure are TCHAR*.
+#else
+#define FIF_TCHAR 0
+#endif
+
+// Helper functions for easy using:
+
+// Helper #1: variables_parse
+// ------------------------
+// The returned string needs to be freed using MS_VARS_FREEMEMORY.
+
+#ifndef VARIABLES_NOHELPER
+__inline static TCHAR *variables_parse(TCHAR *tszFormat, TCHAR *tszExtraText, HANDLE hContact) {
+
+ FORMATINFO fi;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = FORMATINFOV2_SIZE;
+ fi.tszFormat = tszFormat;
+ fi.tszExtraText = tszExtraText;
+ fi.hContact = hContact;
+ fi.flags = FIF_TCHAR;
+
+ return (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+}
+__inline static TCHAR *variables_parse_ex(TCHAR *tszFormat, TCHAR *tszExtraText, HANDLE hContact,
+ TCHAR **tszaTemporaryVars, int cbTemporaryVarsSize) {
+
+ FORMATINFO fi;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = tszFormat;
+ fi.tszExtraText = tszExtraText;
+ fi.hContact = hContact;
+ fi.flags = FIF_TCHAR;
+ fi.tszaTemporaryVars = tszaTemporaryVars;
+ fi.cbTemporaryVarsSize = cbTemporaryVarsSize;
+
+ return (TCHAR *)CallService(MS_VARS_FORMATSTRING_EX, (WPARAM)&fi, 0);
+}
+#endif
+
+// Helper #2: variables_parsedup
+// ------------------------
+// Returns a _strdup()'ed copy of the unparsed string when Variables is not
+// installed, returns a strdup()'ed copy of the parsed result otherwise.
+
+// Note: The returned pointer needs to be released using your own free().
+
+#ifndef VARIABLES_NOHELPER
+__inline static TCHAR *variables_parsedup(TCHAR *tszFormat, TCHAR *tszExtraText, HANDLE hContact) {
+
+ if (ServiceExists(MS_VARS_FORMATSTRING)) {
+ FORMATINFO fi;
+ TCHAR *tszParsed, *tszResult;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = tszFormat;
+ fi.tszExtraText = tszExtraText;
+ fi.hContact = hContact;
+ fi.flags |= FIF_TCHAR;
+ tszParsed = (TCHAR *)CallService(MS_VARS_FORMATSTRING, (WPARAM)&fi, 0);
+ if (tszParsed) {
+ tszResult = _tcsdup(tszParsed);
+ CallService(MS_VARS_FREEMEMORY, (WPARAM)tszParsed, 0);
+ return tszResult;
+ }
+ }
+ return tszFormat?_tcsdup(tszFormat):tszFormat;
+}
+__inline static TCHAR *variables_parsedup_ex(TCHAR *tszFormat, TCHAR *tszExtraText, HANDLE hContact,
+ TCHAR **tszaTemporaryVars, int cbTemporaryVarsSize) {
+
+ if (ServiceExists(MS_VARS_FORMATSTRING)) {
+ FORMATINFO fi;
+ TCHAR *tszParsed, *tszResult;
+
+ ZeroMemory(&fi, sizeof(fi));
+ fi.cbSize = sizeof(fi);
+ fi.tszFormat = tszFormat;
+ fi.tszExtraText = tszExtraText;
+ fi.hContact = hContact;
+ fi.flags |= FIF_TCHAR;
+ fi.tszaTemporaryVars = tszaTemporaryVars;
+ fi.cbTemporaryVarsSize = cbTemporaryVarsSize;
+ tszParsed = (TCHAR *)CallService(MS_VARS_FORMATSTRING_EX, (WPARAM)&fi, 0);
+ if (tszParsed) {
+ tszResult = _tcsdup(tszParsed);
+ CallService(MS_VARS_FREEMEMORY, (WPARAM)tszParsed, 0);
+ return tszResult;
+ }
+ }
+ return tszFormat?_tcsdup(tszFormat):tszFormat;
+}
+#endif
+
+
+
+// --------------------------------------------------------------------------
+// Register tokens
+// --------------------------------------------------------------------------
+
+// Plugins can define tokens which will be parsed by the Variables plugin.
+
+#define MS_VARS_REGISTERTOKEN "Vars/RegisterToken"
+
+// With this service you can define your own token. The newly added tokens
+// using this service are taken into account on every call to
+// MS_VARS_FORMATSTRING.
+
+// Parameters:
+// ------------------------
+// wParam = 0
+// lParam = (LPARAM)(TOKENREGISTER*)&tr
+// See below.
+
+// Return Value:
+// ------------------------
+// Returns 0 on success, nonzero otherwise. Existing tokens will be
+// 'overwritten' if registered twice.
+
+// Needed for szService and parseFunction:
+typedef struct {
+ int cbSize; // You need to check if this is >=sizeof(ARGUMENTSINFO)
+ // (already filled in).
+ FORMATINFO *fi; // Arguments passed to MS_VARS_FORMATSTRING.
+ unsigned int argc; // Number of elements in the argv array.
+ union {
+ char **argv; // Argv[0] will be the token name, the following elements
+ // are the additional arguments.
+ WCHAR **wargv; // If the registered token was registered as a unicode
+ // token, wargv should be accessed.
+ TCHAR **targv;
+ };
+ int flags; // (output) You can set flags here (initially 0), use the
+ // AIF_* flags (see below).
+} ARGUMENTSINFO;
+
+// Available flags for ARGUMENTSINFO:
+// Set the flags of the ARGUMENTSINFO struct to any of these to influence
+// further parsing.
+#define AIF_DONTPARSE 0x01 // Don't parse the result of this function,
+ // usually the result of a token is parsed
+ // again, if the `?` is used as a function
+ // character.
+#define AIF_FALSE 0x02 // The function returned logical false.
+
+// Definition of parse/cleanup functions:
+typedef char* (*VARPARSEFUNCA)(ARGUMENTSINFO *ai);
+typedef WCHAR* (*VARPARSEFUNCW)(ARGUMENTSINFO *ai);
+typedef void (*VARCLEANUPFUNCA)(char *szReturn);
+typedef void (*VARCLEANUPFUNCW)(WCHAR *wszReturn);
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define VARPARSEFUNC VARPARSEFUNCW
+#define VARCLEANUPFUNC VARCLEANUPFUNCW
+#else
+#define VARPARSEFUNC VARPARSEFUNCA
+#define VARCLEANUPFUNC VARCLEANUPFUNCA
+#endif
+
+typedef struct {
+ int cbSize; // Set this to sizeof(TOKENREGISTER).
+ union {
+ char *szTokenString; // Name of the new token to be created, without %,
+ // ?, ! etc. signs (can't be NULL).
+ WCHAR *wszTokenString;
+ TCHAR *tszTokenString;
+ };
+ union {
+ char *szService; // Name of a service that is used to request the
+ // token's value, if no service is used, a function
+ // and TRF_PARSEFUNC must be used.
+ VARPARSEFUNCA parseFunction; // See above, use with TRF_PARSEFUNC.
+ VARPARSEFUNCW parseFunctionW;
+ VARPARSEFUNC parseFunctionT;
+ };
+ union {
+ char *szCleanupService; // Name of a service to be called when the
+ // memory allocated in szService can be freed
+ // (only used when flag VRF_CLEANUP is set,
+ // else set this to NULL).
+ VARCLEANUPFUNCA cleanupFunction; // See above, use with TRF_CLEANUPFUNC.
+ VARCLEANUPFUNCW cleanupFunctionW;
+ VARCLEANUPFUNC cleanupFunctionT;
+ };
+ char *szHelpText; // Help info shown in help dialog (can be NULL). Has to
+ // be in the following format:
+ // "subject\targuments\tdescription"
+ // (Example: "math\t(x, y ,...)\tx + y + ..."), or:
+ // "subject\tdescription"
+ // (Example: "miranda\tPath to the Miranda-IM
+ // executable").
+ // Note: subject and description are translated by
+ // Variables.
+ int memType; // Describes which method Varibale's plugin needs to use to
+ // free the returned buffer, use one of the VR_MEM_* values
+ // (see below). Only valid if the flag VRF_FREEMEM is set,
+ // use TR_MEM_OWNER otherwise).
+ int flags; // Flags to use (see below), one of TRF_* (see below).
+} TOKENREGISTER;
+
+// Available Memory Storage Types:
+// These values describe which method Variables Plugin will use to free the
+// buffer returned by the parse function or service
+#define TR_MEM_VARIABLES 1 // Memory is allocated using the functions
+ // retrieved by MS_VARS_GET_MMI.
+#define TR_MEM_MIRANDA 2 // Memory is allocated using Miranda's Memory
+ // Manager Interface (using the functions
+ // returned by MS_SYSTEM_GET_MMI), if
+ // VRF_FREEMEM is set, the memory will be
+ // freed by Variables.
+#define TR_MEM_OWNER 3 // Memory is owned by the calling plugin
+ // (can't be freed by Variables Plugin
+ // automatically). This should be used if
+ // VRF_FREEMEM is not specified in the flags.
+
+// Available Flags for TOKENREGISTER:
+#define TRF_FREEMEM 0x01 // Variables Plugin will automatically free the
+ // pointer returned by the parse function or
+ // service (which method it will us is
+ // specified in memType -> see above).
+#define TRF_CLEANUP 0x02 // Call cleanup service or function, notifying
+ // that the returned buffer can be freed.
+ // Normally you should use either TRF_FREEMEM
+ // or TRF_CLEANUP.
+#define TRF_PARSEFUNC 0x40 // parseFunction will be used instead of a
+ // service.
+#define TRF_CLEANUPFUNC 0x80 // cleanupFunction will be used instead of a
+ // service.
+#define TRF_USEFUNCS TRF_PARSEFUNC|TRF_CLEANUPFUNC
+#define TRF_UNPARSEDARGS 0x04 // Provide the arguments for the parse
+ // function in their raw (unparsed) form.
+ // By default, arguments are parsed before
+ // presenting them to the parse function.
+#define TRF_FIELD 0x08 // The token can be used as a %field%.
+#define TRF_FUNCTION 0x10 // The token can be used as a ?function().
+ // Normally you should use either TRF_FIELD or
+ // TRF_FUNCTION.
+#define TRF_UNICODE 0x20 // Strings in structure are unicode (WCHAR*).
+ // In this case, the strings pointing to the
+ // arguments in the ARGUMENTS struct are
+ // unicode also. The returned buffer is
+ // expected to be unicode also, and the
+ // unicode parse and cleanup functions are
+ // called.
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define TRF_TCHAR TRF_UNICODE // Strings in structure are TCHAR*.
+#else
+#define TRF_TCHAR 0
+#endif
+
+// Deprecated:
+#define TRF_CALLSVC TRF_CLEANUP
+
+// Callback Service (szService) / parseFunction:
+// ------------------------
+// Service that is called automatically by the Variable's Plugin to resolve a
+// registered variable.
+
+// Parameters:
+// wParam = 0
+// lParam = (LPARAM)(ARGUMENTSINFO *)&ai
+// see above
+
+// Return Value:
+// Needs to return the pointer to a dynamically allocacated string or NULL.
+// A return value of NULL is regarded as an error (eCount will be increaded).
+// Flags in the ARGUMENTSINFO struct can be set (see above).
+
+// Callback Service (szCallbackService) / cleanupFunction:
+// ------------------------
+// This service is called when the memory that was allocated by the parse
+// function or service can be freed. Note: It will only be called when the
+// flag VRF_CLEANUP of TOKENREGISTER is set.
+
+// Parameters:
+// wParam = 0
+// lParam = (LPARAM)(char *)&res
+// Result from parse function or service (pointer to a string).
+
+// Return Value:
+// Should return 0 on success.
+
+
+
+// --------------------------------------------------------------------------
+// Show the help dialog
+// --------------------------------------------------------------------------
+
+// Plugins can invoke Variables' help dialog which can be used for easy input
+// by users.
+
+#define MS_VARS_SHOWHELPEX "Vars/ShowHelpEx"
+
+// This service can be used to open the help dialog of Variables. This dialog
+// provides easy input for the user and/or information about the available
+// tokens.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(HWND)hwndParent
+// lParam = (LPARAM)(VARHELPINFO)&vhi
+// See below.
+
+// Return Value:
+// ------------------------
+// Returns 0 on succes, any other value on error.
+
+typedef struct {
+ int cbSize; // Set to sizeof(VARHELPINFO).
+ FORMATINFO *fi; // Used for both input and output. If this pointer is not
+ // NULL, the information is used as the initial values for
+ // the dialog.
+ HWND hwndCtrl; // Used for both input and output. The window text of this
+ // window will be read and used as the initial input of the
+ // input dialog. If the user presses the OK button the window
+ // text of this window will be set to the text of the input
+ // field and a EN_CHANGE message via WM_COMMAND is send to
+ // this window. (Can be NULL).
+ char *szSubjectDesc; // The description of the %subject% token will be set
+ // to this text, if not NULL. This is translated
+ // automatically.
+ char *szExtraTextDesc; // The description of the %extratext% token will be
+ // set to this text, if not NULL. This is translated
+ // automatically.
+ int flags; // Flags, see below.
+} VARHELPINFO;
+
+
+// Flags for VARHELPINFO
+#define VHF_TOKENS 0x00000001 // Create a dialog with the list of
+ // tokens
+#define VHF_INPUT 0x00000002 // Create a dialog with an input
+ // field (this contains the list of
+ // tokens as well).
+#define VHF_SUBJECT 0x00000004 // Create a dialog to select a
+ // contact for the %subject% token.
+#define VHF_EXTRATEXT 0x00000008 // Create a dialog to enter a text
+ // for the %extratext% token.
+#define VHF_HELP 0x00000010 // Create a dialog with help info.
+#define VHF_HIDESUBJECTTOKEN 0x00000020 // Hide the %subject% token in the
+ // list of tokens.
+#define VHF_HIDEEXTRATEXTTOKEN 0x00000040 // Hide the %extratext% token in
+ // the list of tokens.
+#define VHF_DONTFILLSTRUCT 0x00000080 // Don't fill the struct with the
+ // new information if OK is pressed
+#define VHF_FULLFILLSTRUCT 0x00000100 // Fill all members of the struct
+ // when OK is pressed. By default
+ // only szFormat is set. With this
+ // flag on, hContact and
+ // szExtraText are also set.
+#define VHF_SETLASTSUBJECT 0x00000200 // Set the last contact that was
+ // used in the %subject% dialog in
+ // case fi.hContact is NULL.
+
+// Predefined flags
+#define VHF_FULLDLG VHF_INPUT|VHF_SUBJECT|VHF_EXTRATEXT|VHF_HELP
+#define VHF_SIMPLEDLG VHF_INPUT|VHF_HELP
+#define VHF_NOINPUTDLG VHF_TOKENS|VHF_HELP
+
+// If the service fills information in the struct for szFormat or szExtraText,
+// these members must be free'd using the free function of Variables.
+// If wParam==NULL, the dialog is created modeless. Only one dialog can be
+// shown at the time.
+// If both hwndCtrl and fi are NULL, the user input will not be retrievable.
+// In this case, the dialog is created with only a "Close" button, instead of
+// the "OK" and "Cancel" buttons.
+// In case of modeless dialog and fi != NULL, please make sure this pointer
+// stays valid while the dialog is open.
+
+// Helper function for easy use in standard case:
+#ifndef VARIABLES_NOHELPER
+__inline static int variables_showhelp(HWND hwndDlg, UINT uIDEdit, int flags, char *szSubjectDesc, char *szExtraDesc) {
+
+ VARHELPINFO vhi;
+
+ ZeroMemory(&vhi, sizeof(VARHELPINFO));
+ vhi.cbSize = sizeof(VARHELPINFO);
+ if (flags == 0) {
+ flags = VHF_SIMPLEDLG;
+ }
+ vhi.flags = flags;
+ vhi.hwndCtrl = GetDlgItem(hwndDlg, uIDEdit);
+ vhi.szSubjectDesc = szSubjectDesc;
+ vhi.szExtraTextDesc = szExtraDesc;
+
+ return CallService(MS_VARS_SHOWHELPEX, (WPARAM)hwndDlg, (LPARAM)&vhi);
+}
+#endif
+
+
+#define MS_VARS_GETSKINITEM "Vars/GetSkinItem"
+
+// This service can be used to get the icon you can use for example on the
+// Variables help button in your options screen. You can also get the tooltip
+// text to use with such a button. If icon library is available the icon will
+// be retrieved from icon library manager, otherwise the default is returned.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)0
+// lParam = (LPARAM)VSI_* (see below)
+
+// Return Value:
+// ------------------------
+// Depends on the information to retrieve (see below).
+
+// VSI_ constants
+#define VSI_HELPICON 1 // Can be used on the button accessing the
+ // Variables help dialog. Returns (HICON)hIcon on
+ // success or NULL on failure;
+#define VSI_HELPTIPTEXT 2 // Returns the tooltip text you can use for the
+ // help button. Returns (char *)szTipText, a
+ // static, translated buffer containing the help
+ // text or NULL on error.
+
+// Helper to set the icon on a button accessing the help dialog.
+// Preferably a 16x14 MButtonClass control, but it works on a standard
+// button control as well. If no icon is availble (because of old version of
+// Variables) the string "V" is shown on the button. If Variables is not
+// available, the button will be hidden.
+#ifndef VARIABLES_NOHELPER
+__inline static int variables_skin_helpbutton(HWND hwndDlg, UINT uIDButton) {
+
+ int res;
+ HICON hIcon;
+ TCHAR tszClass[32];
+
+ hIcon = NULL;
+ res = 0;
+ if (ServiceExists(MS_VARS_GETSKINITEM)) {
+ hIcon = (HICON)CallService(MS_VARS_GETSKINITEM, 0, (LPARAM)VSI_HELPICON);
+ }
+ GetClassName(GetDlgItem(hwndDlg, uIDButton), tszClass, sizeof(tszClass));
+ if (!_tcscmp(tszClass, _T("Button"))) {
+ if (hIcon != NULL) {
+ SetWindowLong(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE, GetWindowLong(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE)|BS_ICON);
+ SendMessage(GetDlgItem(hwndDlg, uIDButton), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hIcon);
+ }
+ else {
+ SetWindowLong(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE, GetWindowLong(GetDlgItem(hwndDlg, uIDButton), GWL_STYLE)&~BS_ICON);
+ SetDlgItemText(hwndDlg, uIDButton, _T("V"));
+ }
+ }
+ else if (!_tcscmp(tszClass, MIRANDABUTTONCLASS)) {
+ if (hIcon != NULL) {
+ char *szTipInfo;
+
+ SendMessage(GetDlgItem(hwndDlg, uIDButton), BM_SETIMAGE, (WPARAM)IMAGE_ICON, (LPARAM)hIcon);
+ if (ServiceExists(MS_VARS_GETSKINITEM)) {
+ szTipInfo = (char *)CallService(MS_VARS_GETSKINITEM, 0, (LPARAM)VSI_HELPTIPTEXT);
+ }
+ if (szTipInfo == NULL) {
+ szTipInfo = Translate("Open String Formatting Help");
+ }
+ SendMessage(GetDlgItem(hwndDlg, uIDButton), BUTTONADDTOOLTIP, (WPARAM)szTipInfo, 0);
+ SendDlgItemMessage(hwndDlg, uIDButton, BUTTONSETASFLATBTN, 0, 0);
+ }
+ else {
+ SetDlgItemText(hwndDlg, uIDButton, _T("V"));
+ }
+ }
+ else {
+ res = -1;
+ }
+ ShowWindow(GetDlgItem(hwndDlg, uIDButton), ServiceExists(MS_VARS_FORMATSTRING));
+
+ return res;
+}
+#endif
+
+
+#define MS_VARS_SHOWHELP "Vars/ShowHelp"
+
+// WARNING: This service is obsolete, please use MS_VARS_SHOWHELPEX
+
+// Shows a help dialog where all possible tokens are displayed. The tokens
+// are explained on the dialog, too. The user can edit the initial string and
+// insert as many tokens as he likes.
+
+// Parameters:
+// ------------------------
+// wParam = (HWND)hwndEdit
+// Handle to an edit control in which the modified string
+// should be inserted (When the user clicks OK in the dialog the edited
+// string will be set to hwndEdit) (can be NULL).
+// lParam = (char *)pszInitialString
+// String that the user is provided with initially when
+// the dialog gets opened (If this is NULL then the current text in the
+// hwndEdit edit control will be used) (can be NULL).
+
+// Return Value:
+// ------------------------
+// Returns the handle to the help dialog (HWND).
+
+// Note: Only one help dialog can be opened at a time. When the dialog gets
+// closed an EN_CHANGE of the edit controll will be triggered because the
+// contents were updated. (Only when user selected OK).
+
+// Example:
+// CallService(MS_VARS_SHOWHELP, (WPARAM)hwndEdit, (LPARAM)"some initial text");
+
+// --------------------------------------------------------------------------
+// Retrieve a contact's HANDLE given a string
+// --------------------------------------------------------------------------
+
+#define MS_VARS_GETCONTACTFROMSTRING "Vars/GetContactFromString"
+
+// Searching for contacts in the database. You can find contacts in db by
+// searching for their name, e.g first name.
+
+// Parameters:
+// ------------------------
+// wParam = (WPARAM)(CONTACTSINFO *)&ci
+// See below.
+// lParam = 0
+
+// Return Value:
+// ------------------------
+// Returns number of contacts found matching the given string representation.
+// The hContacts array of CONTACTSINFO struct contains these hContacts after
+// the call.
+
+// Note: The hContacts array needs to be freed after use using
+// MS_VARS_FREEMEMORY.
+
+typedef struct {
+ int cbSize; // Set this to sizeof(CONTACTSINFO).
+ union {
+ char *szContact; // String to search for, e.g. last name (can't be NULL).
+ WCHAR * wszContact;
+ TCHAR *tszContact;
+ };
+ HANDLE *hContacts; // (output) Array of contacts found.
+ DWORD flags; // Contact details that will be matched with the search
+ // string (flags can be combined).
+} CONTACTSINFO;
+
+// Possible flags:
+#define CI_PROTOID 0x00000001 // The contact in the string is encoded
+ // in the format <PROTOID:UNIQUEID>, e.g.
+ // <ICQ:12345678>.
+#define CI_NICK 0x00000002 // Search nick names.
+#define CI_LISTNAME 0x00000004 // Search custom names shown in contact
+ // list.
+#define CI_FIRSTNAME 0x00000008 // Search contact's first names (contact
+ // details).
+#define CI_LASTNAME 0x00000010 // Search contact's last names (contact
+ // details).
+#define CI_EMAIL 0x00000020 // Search contact's email adresses
+ // (contact details).
+#define CI_UNIQUEID 0x00000040 // Search unique ids of the contac, e.g.
+ // UIN.
+#define CI_CNFINFO 0x40000000 // Searches one of the CNF_* flags (set
+ // flags to CI_CNFINFO|CNF_X), only one
+ // CNF_ type possible
+#define CI_UNICODE 0x80000000 // tszContact is a unicode string
+ // (WCHAR*).
+
+#if defined(UNICODE) || defined(_UNICODE)
+#define CI_TCHAR CI_UNICODE // Strings in structure are TCHAR*.
+#else
+#define CI_TCHAR 0
+#endif
+
+
+
+#endif //__M_VARS
diff --git a/Plugins/emoticons/selwin.cpp b/Plugins/emoticons/selwin.cpp
new file mode 100644
index 0000000..0229609
--- /dev/null
+++ b/Plugins/emoticons/selwin.cpp
@@ -0,0 +1,706 @@
+#include "commons.h"
+
+
+#define MIN_COLS 5
+#define MAX_LINES 5
+#define BORDER 5
+
+
+struct EmoticonSelectionData
+{
+ Module *module;
+ COLORREF background;
+ int max_height;
+ int max_width;
+ int lines;
+ int cols;
+ int selection;
+
+ int xPosition;
+ int yPosition;
+ int Direction;
+ HWND hwndTarget;
+ UINT targetMessage;
+ LPARAM targetWParam;
+
+ void SetSelection(HWND hwnd, int sel)
+ {
+ if (sel < 0)
+ sel = -1;
+ if (sel >= module->emoticons.getCount())
+ sel = -1;
+ if (sel != selection)
+ InvalidateRect(hwnd, NULL, FALSE);
+ selection = sel;
+ }
+};
+
+
+HBITMAP CreateBitmap32(int cx, int cy)
+{
+ BITMAPINFO RGB32BitsBITMAPINFO;
+ UINT * ptPixels;
+ HBITMAP DirectBitmap;
+
+ ZeroMemory(&RGB32BitsBITMAPINFO,sizeof(BITMAPINFO));
+ RGB32BitsBITMAPINFO.bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
+ RGB32BitsBITMAPINFO.bmiHeader.biWidth=cx;//bm.bmWidth;
+ RGB32BitsBITMAPINFO.bmiHeader.biHeight=cy;//bm.bmHeight;
+ RGB32BitsBITMAPINFO.bmiHeader.biPlanes=1;
+ RGB32BitsBITMAPINFO.bmiHeader.biBitCount=32;
+
+ DirectBitmap = CreateDIBSection(NULL,
+ (BITMAPINFO *)&RGB32BitsBITMAPINFO,
+ DIB_RGB_COLORS,
+ (void **)&ptPixels,
+ NULL, 0);
+ return DirectBitmap;
+}
+
+
+HWND CreateTooltip(HWND hwnd, RECT &rect, TCHAR *text)
+{
+ // struct specifying control classes to register
+ INITCOMMONCONTROLSEX iccex;
+ HWND hwndTT; // handle to the ToolTip control
+ // struct specifying info about tool in ToolTip control
+ TOOLINFO ti;
+ unsigned int uid = 0; // for ti initialization
+
+ // Load the ToolTip class from the DLL.
+ iccex.dwSize = sizeof(iccex);
+ iccex.dwICC = ICC_BAR_CLASSES;
+
+ if(!InitCommonControlsEx(&iccex))
+ return NULL;
+
+ /* CREATE A TOOLTIP WINDOW */
+ hwndTT = CreateWindowEx(WS_EX_TOPMOST,
+ TOOLTIPS_CLASS,
+ NULL,
+ WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ hwnd,
+ NULL,
+ hInst,
+ NULL
+ );
+
+ /* Gives problem with mToolTip
+ SetWindowPos(hwndTT,
+ HWND_TOPMOST,
+ 0,
+ 0,
+ 0,
+ 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ */
+
+ /* INITIALIZE MEMBERS OF THE TOOLINFO STRUCTURE */
+ ti.cbSize = sizeof(TOOLINFO);
+ ti.uFlags = TTF_SUBCLASS;
+ ti.hwnd = hwnd;
+ ti.hinst = hInst;
+ ti.uId = uid;
+ ti.lpszText = text;
+ // ToolTip control will cover the whole window
+ ti.rect.left = rect.left;
+ ti.rect.top = rect.top;
+ ti.rect.right = rect.right;
+ ti.rect.bottom = rect.bottom;
+
+ /* SEND AN ADDTOOL MESSAGE TO THE TOOLTIP CONTROL WINDOW */
+ SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
+ SendMessage(hwndTT, TTM_SETDELAYTIME, (WPARAM) (DWORD) TTDT_AUTOPOP, (LPARAM) MAKELONG(24 * 60 * 60 * 1000, 0));
+
+ return hwndTT;
+}
+
+
+void AssertInsideScreen(RECT &rc)
+{
+ // Make sure it is inside screen
+ if (IsWinVer98Plus()) {
+ static BOOL loaded = FALSE;
+ static HMONITOR (WINAPI *MyMonitorFromRect)(LPCRECT,DWORD) = NULL;
+ static BOOL (WINAPI *MyGetMonitorInfo)(HMONITOR,LPMONITORINFO) = NULL;
+
+ if (!loaded) {
+ HMODULE hUser32 = GetModuleHandleA("user32");
+ if (hUser32) {
+ MyMonitorFromRect = (HMONITOR(WINAPI*)(LPCRECT,DWORD))GetProcAddress(hUser32,"MonitorFromRect");
+ MyGetMonitorInfo = (BOOL(WINAPI*)(HMONITOR,LPMONITORINFO))GetProcAddress(hUser32,"GetMonitorInfoA");
+ if (MyGetMonitorInfo == NULL)
+ MyGetMonitorInfo = (BOOL(WINAPI*)(HMONITOR,LPMONITORINFO))GetProcAddress(hUser32,"GetMonitorInfo");
+ }
+ loaded = TRUE;
+ }
+
+ if (MyMonitorFromRect != NULL && MyGetMonitorInfo != NULL) {
+ HMONITOR hMonitor;
+ MONITORINFO mi;
+
+ hMonitor = MyMonitorFromRect(&rc, MONITOR_DEFAULTTONEAREST);
+ mi.cbSize = sizeof(mi);
+ MyGetMonitorInfo(hMonitor, &mi);
+
+ if (rc.bottom > mi.rcWork.bottom)
+ OffsetRect(&rc, 0, mi.rcWork.bottom - rc.bottom);
+ if (rc.bottom < mi.rcWork.top)
+ OffsetRect(&rc, 0, mi.rcWork.top - rc.top);
+ if (rc.top > mi.rcWork.bottom)
+ OffsetRect(&rc, 0, mi.rcWork.bottom - rc.bottom);
+ if (rc.top < mi.rcWork.top)
+ OffsetRect(&rc, 0, mi.rcWork.top - rc.top);
+ if (rc.right > mi.rcWork.right)
+ OffsetRect(&rc, mi.rcWork.right - rc.right, 0);
+ if (rc.right < mi.rcWork.left)
+ OffsetRect(&rc, mi.rcWork.left - rc.left, 0);
+ if (rc.left > mi.rcWork.right)
+ OffsetRect(&rc, mi.rcWork.right - rc.right, 0);
+ if (rc.left < mi.rcWork.left)
+ OffsetRect(&rc, mi.rcWork.left - rc.left, 0);
+ }
+ }
+}
+
+
+INT_PTR CALLBACK EmoticonSeletionDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ EmoticonSelectionData *ssd = (EmoticonSelectionData *) lParam;
+ SetWindowLong(hwnd, GWL_USERDATA, (LONG) ssd);
+
+ ssd->selection = -1;
+
+ // Load emoticons
+ ssd->max_height = 4;
+ ssd->max_width = 4;
+
+ HDC hdc = GetDC(hwnd);
+
+ int num_emotes = ssd->module->emoticons.getCount();
+ int i;
+ for(i = 0; i < num_emotes; i++)
+ {
+ Emoticon *e = ssd->module->emoticons[i];
+ if (e->img != NULL)
+ e->img->Load(ssd->max_height, ssd->max_width);
+
+ if (e->img == NULL || e->img->img == NULL)
+ {
+ HFONT hFont;
+ if (ssd->hwndTarget != NULL)
+ {
+ CHARFORMAT2 cf;
+ ZeroMemory(&cf, sizeof(cf));
+ cf.cbSize = sizeof(cf);
+ cf.dwMask = CFM_FACE | CFM_ITALIC | CFM_CHARSET | CFM_FACE | CFM_WEIGHT | CFM_SIZE;
+ SendMessage(ssd->hwndTarget, EM_GETCHARFORMAT, SCF_SELECTION, (LPARAM) &cf);
+
+ LOGFONT lf = {0};
+ lf.lfHeight = -MulDiv(cf.yHeight / 20, GetDeviceCaps(hdc, LOGPIXELSY), 72);
+ lf.lfWeight = cf.wWeight;
+ lf.lfItalic = (cf.dwEffects & CFE_ITALIC) == CFE_ITALIC;
+ lf.lfCharSet = cf.bCharSet;
+ lf.lfPitchAndFamily = cf.bPitchAndFamily;
+ lstrcpyn(lf.lfFaceName, cf.szFaceName, MAX_REGS(lf.lfFaceName));
+
+ hFont = CreateFontIndirect(&lf);
+ }
+ else
+ hFont = (HFONT) SendMessage(hwnd, WM_GETFONT, 0, 0);
+
+ if (hFont != NULL)
+ SelectObject(hdc, hFont);
+
+ RECT rc = { 0, 0, 0xFFFF, 0xFFFF };
+ DrawText(hdc, e->texts[0], lstrlen(e->texts[0]), &rc, DT_CALCRECT | DT_NOPREFIX);
+
+ ssd->max_height = max(ssd->max_height, rc.bottom - rc.top + 1);
+ ssd->max_width = max(ssd->max_width, rc.right - rc.left + 1);
+
+ if (ssd->hwndTarget != NULL)
+ DeleteObject(hFont);
+ }
+ }
+
+ ReleaseDC(hwnd, hdc);
+
+ ssd->cols = num_emotes / MAX_LINES;
+ if (num_emotes % MAX_LINES != 0)
+ ssd->cols++;
+ ssd->cols = max(ssd->cols, MIN_COLS);
+
+ ssd->lines = num_emotes / ssd->cols;
+ if (num_emotes % ssd->cols != 0)
+ ssd->lines++;
+
+ // Calc position
+ int width = ssd->max_width * ssd->cols + (ssd->cols + 1) * BORDER + 1;
+ int height = ssd->max_height * ssd->lines + (ssd->lines + 1) * BORDER + 1;
+
+ int x = ssd->xPosition;
+ int y = ssd->yPosition;
+ switch (ssd->Direction)
+ {
+ case 1:
+ x -= width;
+ break;
+ case 2:
+ x -= width;
+ y -= height;
+ break;
+ case 3:
+ y -= height;
+ break;
+ }
+
+ // Get background
+ ssd->background = RGB(255, 255, 255);
+ if (ssd->hwndTarget != NULL)
+ {
+ ssd->background = SendMessage(ssd->hwndTarget, EM_SETBKGNDCOLOR, 0, ssd->background);
+ SendMessage(ssd->hwndTarget, EM_SETBKGNDCOLOR, 0, ssd->background);
+ }
+
+ RECT rc = { x, y, x + width, y + height };
+ AssertInsideScreen(rc);
+ SetWindowPos(hwnd, HWND_TOPMOST, rc.left, rc.top, width, height, 0);
+
+ for(i = 0; i < ssd->lines; i++)
+ {
+ for(int j = 0; j < ssd->cols; j++)
+ {
+ int index = i * ssd->cols + j;
+ if (index >= ssd->module->emoticons.getCount())
+ break;
+
+ Emoticon *e = ssd->module->emoticons[index];
+
+ RECT fr;
+ fr.left = BORDER + j * (ssd->max_width + BORDER) - 1;
+ fr.right = fr.left + ssd->max_width + 2;
+ fr.top = BORDER + i * (ssd->max_height + BORDER) - 1;
+ fr.bottom = fr.top + ssd->max_height + 2;
+
+ Buffer<TCHAR> tt;
+ if (e->description[0] != _T('\0'))
+ {
+ tt += _T(" ");
+ tt += e->description;
+ tt.translate();
+ tt += _T(" ");
+ }
+
+ for(int k = 0; k < e->texts.getCount(); k++)
+ {
+ tt += _T(" ");
+ tt += e->texts[k];
+ tt += _T(" ");
+ }
+ tt.pack();
+
+ e->tt = CreateTooltip(hwnd, fr, tt.str);
+ }
+ }
+
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = TME_HOVER | TME_LEAVE;
+ tme.hwndTrack = hwnd;
+ tme.dwHoverTime = HOVER_DEFAULT;
+ TrackMouseEvent(&tme);
+
+ return TRUE;
+ }
+
+ case WM_PAINT:
+ {
+ RECT r;
+ if (GetUpdateRect(hwnd, &r, FALSE))
+ {
+ EmoticonSelectionData *ssd = (EmoticonSelectionData *) GetWindowLong(hwnd, GWL_USERDATA);
+
+ PAINTSTRUCT ps;
+
+ HDC hdc_orig = BeginPaint(hwnd, &ps);
+
+ RECT rc;
+ GetClientRect(hwnd, &rc);
+
+ // Create double buffer
+ HDC hdc = CreateCompatibleDC(hdc_orig);
+ HBITMAP hBmp = CreateBitmap32(rc.right, rc.bottom);
+ SelectObject(hdc, hBmp);
+
+ SetBkMode(hdc, TRANSPARENT);
+
+ // Erase background
+ HBRUSH hB = CreateSolidBrush(ssd->background);
+ FillRect(hdc, &rc, hB);
+ DeleteObject(hB);
+
+ // Draw emoticons
+ for(int i = 0; i < ssd->lines; i++)
+ {
+ for(int j = 0; j < ssd->cols; j++)
+ {
+ int index = i * ssd->cols + j;
+ if (index >= ssd->module->emoticons.getCount())
+ break;
+
+ Emoticon *e = ssd->module->emoticons[index];
+ if (e->img == NULL || e->img->img == NULL)
+ {
+ HFONT hFont;
+ if (ssd->hwndTarget != NULL)
+ {
+ CHARFORMAT2 cf;
+ ZeroMemory(&cf, sizeof(cf));
+ cf.cbSize = sizeof(cf);
+ cf.dwMask = CFM_FACE | CFM_ITALIC | CFM_CHARSET | CFM_FACE | CFM_WEIGHT | CFM_SIZE | CFM_COLOR;
+ SendMessage(ssd->hwndTarget, EM_GETCHARFORMAT, SCF_DEFAULT, (LPARAM) &cf);
+
+ LOGFONT lf = {0};
+ lf.lfHeight = -MulDiv(cf.yHeight / 20, GetDeviceCaps(hdc, LOGPIXELSY), 72);
+ lf.lfWeight = cf.wWeight;
+ lf.lfItalic = (cf.dwEffects & CFE_ITALIC) == CFE_ITALIC;
+ lf.lfCharSet = cf.bCharSet;
+ lf.lfPitchAndFamily = cf.bPitchAndFamily;
+ lstrcpyn(lf.lfFaceName, cf.szFaceName, MAX_REGS(lf.lfFaceName));
+
+ hFont = CreateFontIndirect(&lf);
+ SetTextColor(hdc, cf.crTextColor);
+ }
+ else
+ hFont = (HFONT) SendMessage(hwnd, WM_GETFONT, 0, 0);
+
+ if (hFont != NULL)
+ SelectObject(hdc, hFont);
+
+ RECT rc = { 0, 0, 0xFFFF, 0xFFFF };
+ DrawText(hdc, e->texts[0], lstrlen(e->texts[0]), &rc, DT_CALCRECT | DT_NOPREFIX);
+
+ int height = rc.bottom - rc.top + 1;
+ int width = rc.right - rc.left + 1;
+
+ rc.left = BORDER + j * (ssd->max_width + BORDER) + (ssd->max_width - width) / 2;
+ rc.top = BORDER + i * (ssd->max_height + BORDER) + (ssd->max_height - height) / 2;
+
+ rc.right = rc.left + width;
+ rc.bottom = rc.top + height;
+
+ DrawText(hdc, e->texts[0], lstrlen(e->texts[0]), &rc, DT_NOPREFIX);
+
+ if (ssd->hwndTarget != NULL)
+ DeleteObject(hFont);
+ }
+ else
+ {
+ BITMAP bmp;
+ GetObject(e->img->img, sizeof(bmp), &bmp);
+
+ int x = BORDER + j * (ssd->max_width + BORDER) + (ssd->max_width - bmp.bmWidth) / 2;
+ int y = BORDER + i * (ssd->max_height + BORDER) + (ssd->max_height - bmp.bmHeight) / 2;
+
+ HDC hdc_img = CreateCompatibleDC(hdc);
+ HBITMAP old_bmp = (HBITMAP) SelectObject(hdc_img, e->img->img);
+
+ if (e->img->transparent)
+ {
+ BLENDFUNCTION bf = {0};
+ bf.SourceConstantAlpha = 255;
+ bf.AlphaFormat = AC_SRC_ALPHA;
+ AlphaBlend(hdc, x, y, bmp.bmWidth, bmp.bmHeight, hdc_img, 0, 0, bmp.bmWidth, bmp.bmHeight, bf);
+ }
+ else
+ {
+ BitBlt(hdc, x, y, bmp.bmWidth, bmp.bmHeight, hdc_img, 0, 0, SRCCOPY);
+ }
+
+ SelectObject(hdc_img, old_bmp);
+ DeleteDC(hdc_img);
+
+ }
+
+ if (ssd->selection == index)
+ {
+ RECT fr;
+ fr.left = BORDER + j * (ssd->max_width + BORDER) - 1;
+ fr.right = fr.left + ssd->max_width + 2;
+ fr.top = BORDER + i * (ssd->max_height + BORDER) - 1;
+ fr.bottom = fr.top + ssd->max_height + 2;
+ FrameRect(hdc, &fr, (HBRUSH) GetStockObject(GRAY_BRUSH));
+ }
+ }
+ }
+
+ // Copy buffer to screen
+ BitBlt(hdc_orig, rc.left, rc.top, rc.right - rc.left,
+ rc.bottom - rc.top, hdc, rc.left, rc.top, SRCCOPY);
+ DeleteDC(hdc);
+ DeleteObject(hBmp);
+
+ EndPaint(hwnd, &ps);
+ }
+
+ return TRUE;
+ }
+
+ case WM_MOUSELEAVE:
+ {
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = TME_HOVER;
+ tme.hwndTrack = hwnd;
+ tme.dwHoverTime = HOVER_DEFAULT;
+ TrackMouseEvent(&tme);
+ }
+ case WM_NCMOUSEMOVE:
+ {
+ EmoticonSelectionData *ssd = (EmoticonSelectionData *) GetWindowLong(hwnd, GWL_USERDATA);
+ ssd->SetSelection(hwnd, -1);
+ break;
+ }
+
+ case WM_MOUSEHOVER:
+ {
+ TRACKMOUSEEVENT tme;
+ tme.cbSize = sizeof(TRACKMOUSEEVENT);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = hwnd;
+ tme.dwHoverTime = HOVER_DEFAULT;
+ TrackMouseEvent(&tme);
+ }
+ case WM_MOUSEMOVE:
+ {
+ EmoticonSelectionData *ssd = (EmoticonSelectionData *) GetWindowLong(hwnd, GWL_USERDATA);
+
+ POINT p;
+ p.x = LOWORD(lParam);
+ p.y = HIWORD(lParam);
+
+ int col;
+ if (p.x % (BORDER + ssd->max_width) < BORDER)
+ col = -1;
+ else
+ col = p.x / (BORDER + ssd->max_width);
+
+ int line;
+ if (p.y % (BORDER + ssd->max_height) < BORDER)
+ line = -1;
+ else
+ line = p.y / (BORDER + ssd->max_height);
+
+ int index = line * ssd->cols + col;
+
+ if (col >= 0 && line >= 0 && index < ssd->module->emoticons.getCount())
+ {
+ ssd->SetSelection(hwnd, index);
+ }
+ else
+ {
+ ssd->SetSelection(hwnd, -1);
+ }
+
+ break;
+ }
+
+ case WM_GETDLGCODE:
+ {
+ if (lParam != NULL)
+ {
+ static DWORD last_time = 0;
+
+ MSG *msg = (MSG* ) lParam;
+ if (msg->message == WM_KEYDOWN && msg->time != last_time)
+ {
+ last_time = msg->time;
+
+ if (msg->wParam == VK_UP)
+ {
+ EmoticonSelectionData *ssd = (EmoticonSelectionData *) GetWindowLong(hwnd, GWL_USERDATA);
+
+ if (ssd->selection < 0)
+ {
+ ssd->SetSelection(hwnd, (ssd->lines - 1) * ssd->cols);
+ }
+ else
+ {
+ int index = (ssd->selection - ssd->cols) % ssd->module->emoticons.getCount();
+ if (index < 0)
+ index += ssd->module->emoticons.getCount();
+ ssd->SetSelection(hwnd, index);
+ }
+ }
+ else if (msg->wParam == VK_DOWN)
+ {
+ EmoticonSelectionData *ssd = (EmoticonSelectionData *) GetWindowLong(hwnd, GWL_USERDATA);
+
+ if (ssd->selection < 0)
+ {
+ ssd->SetSelection(hwnd, 0);
+ }
+ else
+ {
+ ssd->SetSelection(hwnd, (ssd->selection + ssd->cols) % ssd->module->emoticons.getCount());
+ }
+ }
+ else if (msg->wParam == VK_LEFT)
+ {
+ EmoticonSelectionData *ssd = (EmoticonSelectionData *) GetWindowLong(hwnd, GWL_USERDATA);
+
+ if (ssd->selection < 0)
+ {
+ ssd->SetSelection(hwnd, ssd->cols - 1);
+ }
+ else
+ {
+ int index = (ssd->selection - 1) % ssd->module->emoticons.getCount();
+ if (index < 0)
+ index += ssd->module->emoticons.getCount();
+ ssd->SetSelection(hwnd, index);
+ }
+ }
+ else if (msg->wParam == VK_RIGHT)
+ {
+ EmoticonSelectionData *ssd = (EmoticonSelectionData *) GetWindowLong(hwnd, GWL_USERDATA);
+
+ if (ssd->selection < 0)
+ {
+ ssd->SetSelection(hwnd, 0);
+ }
+ else
+ {
+ ssd->SetSelection(hwnd, (ssd->selection + 1) % ssd->module->emoticons.getCount());
+ }
+ }
+ else if (msg->wParam == VK_HOME)
+ {
+ EmoticonSelectionData *ssd = (EmoticonSelectionData *) GetWindowLong(hwnd, GWL_USERDATA);
+ ssd->SetSelection(hwnd, 0);
+ }
+ else if (msg->wParam == VK_END)
+ {
+ EmoticonSelectionData *ssd = (EmoticonSelectionData *) GetWindowLong(hwnd, GWL_USERDATA);
+ ssd->SetSelection(hwnd, ssd->module->emoticons.getCount() - 1);
+ }
+ }
+ }
+
+ return DLGC_WANTALLKEYS;
+ }
+
+ case WM_ACTIVATE:
+ {
+ if (wParam == WA_INACTIVE)
+ PostMessage(hwnd, WM_CLOSE, 0, 0);
+ break;
+ }
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDOK:
+ PostMessage(hwnd, WM_LBUTTONUP, 0, 0);
+ break;
+
+ case IDCANCEL:
+ PostMessage(hwnd, WM_CLOSE, 0, 0);
+ break;
+ }
+ break;
+ }
+
+ case WM_LBUTTONUP:
+ {
+ EmoticonSelectionData *ssd = (EmoticonSelectionData *) GetWindowLong(hwnd, GWL_USERDATA);
+ if (ssd->selection >= 0 && ssd->hwndTarget != NULL)
+ {
+ if (opts.only_replace_isolated)
+ {
+ TCHAR tmp[16];
+ mir_sntprintf(tmp, MAX_REGS(tmp), _T(" %s "), ssd->module->emoticons[ssd->selection]->texts[0]);
+ SendMessage(ssd->hwndTarget, ssd->targetMessage, ssd->targetWParam, (LPARAM) tmp);
+ }
+ else
+ SendMessage(ssd->hwndTarget, ssd->targetMessage, ssd->targetWParam, (LPARAM) ssd->module->emoticons[ssd->selection]->texts[0]);
+ }
+
+ PostMessage(hwnd, WM_CLOSE, 0, 0);
+ break;
+ }
+
+ case WM_CLOSE:
+ {
+ EmoticonSelectionData *ssd = (EmoticonSelectionData *) GetWindowLong(hwnd, GWL_USERDATA);
+ SetWindowLong(hwnd, GWL_USERDATA, NULL);
+
+ for(int i = 0; i < ssd->module->emoticons.getCount(); i++)
+ {
+ Emoticon *e = ssd->module->emoticons[i];
+
+ if (e->tt != NULL)
+ {
+ DestroyWindow(e->tt);
+ e->tt = NULL;
+ }
+ }
+
+ DestroyWindow(hwnd);
+
+ SetFocus(ssd->hwndTarget);
+ delete ssd;
+ break;
+ }
+ }
+
+ return FALSE;
+}
+
+int ShowSelectionService(WPARAM wParam, LPARAM lParam)
+{
+ SMADD_SHOWSEL3 *sss = (SMADD_SHOWSEL3 *)lParam;
+ if (sss == NULL || sss->cbSize < sizeof(SMADD_SHOWSEL3))
+ return FALSE;
+
+ const char *proto = NULL;
+ if (sss->hContact != NULL)
+ {
+ HANDLE hReal = GetRealContact(sss->hContact);
+ proto = (char *) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM) hReal, 0);
+ }
+ if (proto == NULL)
+ proto = sss->Protocolname;
+ if (proto == NULL)
+ return FALSE;
+
+ Module *m = GetModule(proto);
+ if (m == NULL)
+ return FALSE;
+
+ EmoticonSelectionData * ssd = new EmoticonSelectionData();
+ ssd->module = m;
+
+ ssd->xPosition = sss->xPosition;
+ ssd->yPosition = sss->yPosition;
+ ssd->Direction = sss->Direction;
+
+ ssd->hwndTarget = sss->hwndTarget;
+ ssd->targetMessage = sss->targetMessage;
+ ssd->targetWParam = sss->targetWParam;
+
+ CreateDialogParam(hInst, MAKEINTRESOURCE(IDD_EMOTICON_SELECTION), sss->hwndParent,
+ EmoticonSeletionDlgProc, (LPARAM) ssd);
+
+ return TRUE;
+}
+
diff --git a/Plugins/emoticons/selwin.h b/Plugins/emoticons/selwin.h
new file mode 100644
index 0000000..b55b4c6
--- /dev/null
+++ b/Plugins/emoticons/selwin.h
@@ -0,0 +1,29 @@
+/*
+Copyright (C) 2008 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __SELWIN_H__
+# define __SELWIN_H__
+
+
+int ShowSelectionService(WPARAM wParam, LPARAM lParam);
+
+
+
+#endif // __SELWIN_H__
diff --git a/Plugins/utils/ContactAsyncQueue.cpp b/Plugins/utils/ContactAsyncQueue.cpp
new file mode 100644
index 0000000..7be4cfe
--- /dev/null
+++ b/Plugins/utils/ContactAsyncQueue.cpp
@@ -0,0 +1,222 @@
+/*
+Copyright (C) 2006 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+#include "ContactAsyncQueue.h"
+#include <process.h>
+
+
+// Itens with higher time at end
+static int QueueSortItems(const QueueItem *i1, const QueueItem *i2)
+{
+ return i1->check_time - i2->check_time;
+}
+
+// Itens with higher time at end
+static void ContactAsyncQueueThread(void *obj)
+{
+ ((ContactAsyncQueue *)obj)->Thread();
+}
+
+ContactAsyncQueue::ContactAsyncQueue(pfContactAsyncQueueCallback fContactAsyncQueueCallback, int initialSize)
+ : queue(30, QueueSortItems)
+{
+ hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ finished = 0;
+ callback = fContactAsyncQueueCallback;
+
+ InitializeCriticalSection(&cs);
+
+ _beginthread(ContactAsyncQueueThread, 0, this);
+ //mir_forkthread(ContactAsyncQueueThread, this);
+}
+
+ContactAsyncQueue::~ContactAsyncQueue()
+{
+ if (finished == 0)
+ finished = 1;
+ SetEvent(hEvent);
+ int count = 0;
+ while(finished != 2 && ++count < 50)
+ Sleep(10);
+
+ for (int i = 0; i < queue.getCount(); i++)
+ if (queue[i] != NULL)
+ mir_free(queue[i]);
+
+ DeleteCriticalSection(&cs);
+}
+
+void ContactAsyncQueue::Lock()
+{
+ EnterCriticalSection(&cs);
+}
+
+void ContactAsyncQueue::Release()
+{
+ LeaveCriticalSection(&cs);
+}
+
+void ContactAsyncQueue::RemoveAll(HANDLE hContact)
+{
+ Lock();
+
+ for (int i = queue.getCount() - 1; i >= 0; --i)
+ {
+ QueueItem *item = queue[i];
+
+ if (item->hContact == hContact)
+ {
+ queue.remove(i);
+ mir_free(item);
+ }
+ }
+
+ Release();
+}
+
+void ContactAsyncQueue::RemoveAllConsiderParam(HANDLE hContact, void *param)
+{
+ Lock();
+
+ for (int i = queue.getCount() - 1; i >= 0; --i)
+ {
+ QueueItem *item = queue[i];
+
+ if (item->hContact == hContact && item->param == param)
+ {
+ queue.remove(i);
+ mir_free(item);
+ }
+ }
+
+ Release();
+}
+
+void ContactAsyncQueue::Add(int waitTime, HANDLE hContact, void *param)
+{
+ Lock();
+
+ InternalAdd(waitTime, hContact, param);
+
+ Release();
+}
+
+void ContactAsyncQueue::AddIfDontHave(int waitTime, HANDLE hContact, void *param)
+{
+ Lock();
+
+ int i;
+ for (i = queue.getCount() - 1; i >= 0; --i)
+ if (queue[i]->hContact == hContact)
+ break;
+
+ if (i < 0)
+ InternalAdd(waitTime, hContact, param);
+
+ Release();
+}
+
+void ContactAsyncQueue::AddAndRemovePrevious(int waitTime, HANDLE hContact, void *param)
+{
+ Lock();
+
+ RemoveAll(hContact);
+ InternalAdd(waitTime, hContact, param);
+
+ Release();
+}
+
+void ContactAsyncQueue::AddAndRemovePreviousConsiderParam(int waitTime, HANDLE hContact, void *param)
+{
+ Lock();
+
+ RemoveAllConsiderParam(hContact, param);
+ InternalAdd(waitTime, hContact, param);
+
+ Release();
+}
+
+void ContactAsyncQueue::InternalAdd(int waitTime, HANDLE hContact, void *param)
+{
+ QueueItem *item = (QueueItem *) mir_alloc(sizeof(QueueItem));
+ item->hContact = hContact;
+ item->check_time = GetTickCount() + waitTime;
+ item->param = param;
+
+ queue.insert(item);
+
+ SetEvent(hEvent);
+}
+
+void ContactAsyncQueue::Thread()
+{
+ while (!finished)
+ {
+ ResetEvent(hEvent);
+
+ Lock();
+
+ if (queue.getCount() <= 0)
+ {
+ // No items, so supend thread
+ Release();
+
+ wait(/*INFINITE*/ 2 * 60 * 1000);
+ }
+ else
+ {
+ // Take a look at first item
+ QueueItem *qi = queue[0];
+
+ int dt = qi->check_time - GetTickCount();
+ if (dt > 0)
+ {
+ // Not time to request yet, wait...
+ Release();
+
+ wait(dt);
+ }
+ else
+ {
+ // Will request this item
+ queue.remove(0);
+
+ Release();
+
+ callback(qi->hContact, qi->param);
+
+ mir_free(qi);
+ }
+ }
+ }
+
+ finished = 2;
+}
+
+void ContactAsyncQueue::wait(int time)
+{
+ if (!finished)
+ WaitForSingleObject(hEvent, time);
+}
+
+
+
+
+
+
diff --git a/Plugins/utils/ContactAsyncQueue.h b/Plugins/utils/ContactAsyncQueue.h
new file mode 100644
index 0000000..a19ba04
--- /dev/null
+++ b/Plugins/utils/ContactAsyncQueue.h
@@ -0,0 +1,93 @@
+/*
+Copyright (C) 2006 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __CONTACTASYNCQUEUE_H__
+# define __CONTACTASYNCQUEUE_H__
+
+#ifndef MIRANDA_VER
+#define MIRANDA_VER 0x0700
+#endif
+
+#include <windows.h>
+#include <newpluginapi.h>
+#include <m_system_cpp.h>
+
+
+typedef void (*pfContactAsyncQueueCallback) (HANDLE hContact, void *param);
+
+
+struct QueueItem
+{
+ DWORD check_time;
+ HANDLE hContact;
+ void *param;
+};
+
+
+class ContactAsyncQueue
+{
+public:
+
+ ContactAsyncQueue(pfContactAsyncQueueCallback fContactAsyncQueueCallback, int initialSize = 10);
+ ~ContactAsyncQueue();
+
+ inline int Size() const { return queue.getCount(); }
+ inline int Remove(int idx) { mir_free(queue[idx]); return queue.remove(idx); }
+ inline QueueItem* Get(int idx) const { return queue[idx]; }
+
+
+ void RemoveAll(HANDLE hContact);
+ void RemoveAllConsiderParam(HANDLE hContact, void *param);
+ void Add(int waitTime, HANDLE hContact, void *param = NULL);
+ void AddIfDontHave(int waitTime, HANDLE hContact, void *param = NULL);
+ void AddAndRemovePrevious(int waitTime, HANDLE hContact, void *param = NULL);
+ void AddAndRemovePreviousConsiderParam(int waitTime, HANDLE hContact, void *param = NULL);
+
+ void Lock();
+ void Release();
+
+
+ void Thread();
+
+private:
+
+ LIST<QueueItem> queue;
+
+ CRITICAL_SECTION cs;
+ pfContactAsyncQueueCallback callback;
+ HANDLE hEvent;
+ int finished;
+
+
+ void InternalAdd(int waitTime, HANDLE hContact, void *param);
+ void wait(int time);
+};
+
+
+
+
+
+
+
+
+
+
+
+#endif // __CONTACTASYNCQUEUE_H__
diff --git a/Plugins/utils/mir_buffer.h b/Plugins/utils/mir_buffer.h
new file mode 100644
index 0000000..f72da9e
--- /dev/null
+++ b/Plugins/utils/mir_buffer.h
@@ -0,0 +1,452 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __MIR_BUFFER_H__
+# define __MIR_BUFFER_H__
+
+#include <windows.h>
+
+#include "mir_memory.h"
+#include <m_variables.h>
+
+
+template<class T>
+static int __bvsnprintf(T *str, size_t size, const T *fmt, va_list args)
+{
+ return 0;
+}
+
+template<>
+static inline int __bvsnprintf<char>(char *str, size_t size, const char *fmt, va_list args)
+{
+ return _vsnprintf(str, size, fmt, args);
+}
+
+template<>
+static inline int __bvsnprintf<wchar_t>(wchar_t *str, size_t size, const wchar_t *fmt, va_list args)
+{
+ return _vsnwprintf(str, size, fmt, args);
+}
+
+template<class T>
+static inline int __blen(const T *str)
+{
+ return 0;
+}
+
+template<>
+static inline int __blen<char>(const char *str)
+{
+ return strlen(str);
+}
+
+template<>
+static inline int __blen<wchar_t>(const wchar_t *str)
+{
+ return lstrlenW(str);
+}
+
+template<class T>
+static inline T * __bTranslate(const T *str)
+{
+ return 0;
+}
+
+template<>
+static inline char * __bTranslate<char>(const char *str)
+{
+ return Translate(str);
+}
+
+template<>
+static inline wchar_t * __bTranslate<wchar_t>(const wchar_t *str)
+{
+ return TranslateW(str);
+}
+
+
+template<class O, class D>
+static void __bcopy(D *dest, const O *orig, size_t len)
+{
+}
+
+template<>
+static void __bcopy(char *dest, const char *orig, size_t len)
+{
+ strncpy(dest, orig, len);
+}
+
+template<>
+static void __bcopy(WCHAR *dest, const WCHAR *orig, size_t len)
+{
+ wcsncpy(dest, orig, len);
+}
+
+template<>
+static void __bcopy(WCHAR *dest, const char *orig, size_t len)
+{
+ MultiByteToWideChar(CallService("LangPack/GetCodePage", 0, 0), 0, orig, len, dest, len);
+}
+
+template<>
+static void __bcopy(char *dest, const WCHAR *orig, size_t len)
+{
+ WideCharToMultiByte(CallService("LangPack/GetCodePage", 0, 0), 0, orig, len, dest, len, NULL, NULL);
+}
+
+
+
+template<class T>
+class Buffer
+{
+ public:
+ size_t len;
+ T *str;
+
+ Buffer() : len(0), str(NULL), size(0) {}
+
+ Buffer(T in)
+ {
+ str = in;
+ size = len = __blen(in);
+ }
+
+ ~Buffer()
+ {
+ free();
+ }
+
+ void pack()
+ {
+ if (str != NULL)
+ str[len] = 0;
+ }
+
+ void alloc(size_t total)
+ {
+ if (total > size)
+ {
+ size = total + 256 - total % 256;
+ if (str == NULL)
+ str = (T *) mir_alloc(size * sizeof(T));
+ else
+ str = (T *) mir_realloc(str, size * sizeof(T));
+ }
+ }
+
+ void free()
+ {
+ if (str != NULL)
+ {
+ mir_free(str);
+ str = NULL;
+ len = size = 0;
+ }
+ }
+
+ void clear()
+ {
+ len = 0;
+ }
+
+ void append(T app)
+ {
+ alloc(len + 1);
+
+ str[len] = app;
+ len++;
+ }
+
+ void append(const char *app, size_t appLen = -1)
+ {
+ if (appLen == -1)
+ appLen = __blen(app);
+
+ size_t total = len + appLen + 1;
+ alloc(total);
+
+ __bcopy(&str[len], app, appLen);
+ len += appLen;
+ }
+
+ void append(const WCHAR *app, size_t appLen = -1)
+ {
+ if (appLen == -1)
+ appLen = __blen(app);
+
+ size_t total = len + appLen + 1;
+ alloc(total);
+
+ __bcopy(&str[len], app, appLen);
+ len += appLen;
+ }
+
+ void appendPrintf(const T *app, ...)
+ {
+ size_t total = len + 512;
+ alloc(total);
+
+ va_list arg;
+ va_start(arg, app);
+ total = __bvsnprintf<T>(&str[len], size - len - 1, app, arg);
+ if (total < 0)
+ total = size - len - 1;
+ len += total;
+ }
+
+ void insert(size_t pos, T *app, size_t appLen = -1)
+ {
+ if (pos > len)
+ pos = len;
+ if (pos < 0)
+ pos = 0;
+
+ if (appLen == -1)
+ appLen = __blen(app);
+
+ alloc(len + appLen + 1);
+
+ if (pos < len)
+ memmove(&str[pos + appLen], &str[pos], (len - pos) * sizeof(T));
+ memmove(&str[pos], app, appLen * sizeof(T));
+
+ len += appLen;
+ }
+
+ void replace(size_t start, size_t end, T *app, size_t appLen = -1)
+ {
+ if (start > len)
+ start = len;
+ if (start < 0)
+ start = 0;
+
+ if (end > len)
+ end = len;
+ if (end < start)
+ end = start;
+
+ if (appLen == -1)
+ appLen = __blen(app);
+
+ size_t oldLen = end - start;
+ if (oldLen < appLen)
+ alloc(len + appLen - oldLen + 1);
+
+ if (end < len && oldLen != appLen)
+ memmove(&str[start + appLen], &str[end], (len - end) * sizeof(T));
+ memmove(&str[start], app, appLen * sizeof(T));
+
+ len += appLen - oldLen;
+ }
+
+ void translate()
+ {
+ if (str == NULL || len == 0)
+ return;
+
+ str[len] = 0;
+ T *tmp = __bTranslate(str);
+ len = __blen(tmp);
+ alloc(len + 1);
+ memmove(str, tmp, len * sizeof(T));
+ }
+
+ T *appender(size_t appLen)
+ {
+ alloc(len + appLen + 1);
+ T *ret = &str[len];
+ len += appLen;
+ return ret;
+ }
+
+ T *lock(size_t maxSize)
+ {
+ alloc(len + maxSize + 1);
+ return &str[len];
+ }
+
+ void release()
+ {
+ len += max(__blen(&str[len]), size - len - 1);
+ }
+
+ T *detach()
+ {
+ T *ret = str;
+ str = NULL;
+ len = 0;
+ return ret;
+ }
+
+ void trimRight()
+ {
+ if (str == NULL)
+ return;
+
+ int e;
+ for(e = len-1; e >= 0 && (str[e] == (T)' '
+ || str[e] == (T)'\t'
+ || str[e] == (T)'\r'
+ || str[e] == (T)'\n'); e--) ;
+ len = e+1;
+ }
+
+ void trimLeft()
+ {
+ if (str == NULL)
+ return;
+
+ int s;
+ for(s = 0; str[s] == (T)' '
+ || str[s] == (T)'\t'
+ || str[s] == (T)'\r'
+ || str[s] == (T)'\n'; s++) ;
+ if (s > 0)
+ {
+ memmove(str, &str[s], (len - s) * sizeof(T));
+ len -= s;
+ }
+ }
+
+ void trim()
+ {
+ trimRight();
+ trimLeft();
+ }
+
+ Buffer<T>& operator+=(const char *txt)
+ {
+ append(txt);
+ return *this;
+ }
+
+ Buffer<T>& operator+=(const WCHAR *txt)
+ {
+ append(txt);
+ return *this;
+ }
+
+
+ private:
+ size_t size;
+};
+
+
+static void ReplaceVars(Buffer<TCHAR> *buffer, HANDLE hContact, TCHAR **variables, int numVariables)
+{
+ if (buffer->len < 3)
+ return;
+
+ if (numVariables <= 0)
+ return;
+
+ for(size_t i = buffer->len - 1; i > 0; i--)
+ {
+ if (buffer->str[i] == _T('%'))
+ {
+ // Find previous
+ size_t j;
+ for(j = i - 1; j > 0 && ((buffer->str[j] >= _T('a') && buffer->str[j] <= _T('z'))
+ || (buffer->str[j] >= _T('A') && buffer->str[j] <= _T('Z'))
+ || buffer->str[j] == _T('-')
+ || buffer->str[j] == _T('_')); j--) ;
+
+ if (buffer->str[j] == _T('%'))
+ {
+ size_t foundLen = i - j + 1;
+ if (foundLen == 9 && _tcsncmp(&buffer->str[j], _T("%contact%"), 9) == 0)
+ {
+ buffer->replace(j, i + 1, (TCHAR *) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM) hContact, GCDNF_TCHAR));
+ }
+ else if (foundLen == 6 && _tcsncmp(&buffer->str[j], _T("%date%"), 6) == 0)
+ {
+ TCHAR tmp[128];
+ DBTIMETOSTRINGT tst = {0};
+ tst.szFormat = _T("d s");
+ tst.szDest = tmp;
+ tst.cbDest = 128;
+ CallService(MS_DB_TIME_TIMESTAMPTOSTRINGT, (WPARAM) time(NULL), (LPARAM) &tst);
+ buffer->replace(j, i + 1, tmp);
+ }
+ else
+ {
+ for(int k = 0; k < numVariables; k += 2)
+ {
+ size_t len = lstrlen(variables[k]);
+ if (foundLen == len + 2 && _tcsncmp(&buffer->str[j]+1, variables[k], len) == 0)
+ {
+ buffer->replace(j, i + 1, variables[k + 1]);
+ break;
+ }
+ }
+ }
+ }
+
+ i = j;
+ if (i == 0)
+ break;
+ }
+ else if (buffer->str[i] == _T('\\') && i+1 <= buffer->len-1 && buffer->str[i+1] == _T('n'))
+ {
+ buffer->str[i] = _T('\r');
+ buffer->str[i+1] = _T('\n');
+ }
+ }
+}
+
+
+static void ReplaceTemplate(Buffer<TCHAR> *out, HANDLE hContact, TCHAR *templ, TCHAR **vars, int numVars)
+{
+ if (ServiceExists(MS_VARS_FORMATSTRING_EX))
+ {
+ TCHAR *tmp = variables_parse_ex(templ, NULL, hContact, vars, numVars);
+ if (tmp != NULL)
+ {
+ out->append(tmp);
+ variables_free(tmp);
+ out->pack();
+ return;
+ }
+ }
+
+ if (ServiceExists(MS_VARS_FORMATSTRING))
+ {
+ out->append(templ);
+ ReplaceVars(out, hContact, vars, numVars);
+ out->pack();
+
+ TCHAR *tmp = variables_parse(out->str, NULL, hContact);
+ if (tmp != NULL)
+ {
+ out->clear();
+ out->append(tmp);
+ variables_free(tmp);
+ out->pack();
+ return;
+ }
+ }
+
+ out->append(templ);
+ ReplaceVars(out, hContact, vars, numVars);
+ out->pack();
+}
+
+
+#endif // __MIR_BUFFER_H__
diff --git a/Plugins/utils/mir_icons.cpp b/Plugins/utils/mir_icons.cpp
new file mode 100644
index 0000000..1ee7999
--- /dev/null
+++ b/Plugins/utils/mir_icons.cpp
@@ -0,0 +1,49 @@
+/*
+Copyright (C) 2007 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "mir_icons.h"
+
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_icolib.h>
+
+
+HICON LoadIconEx(const char *iconName, BOOL copy)
+{
+ if (!ServiceExists(MS_SKIN2_GETICON))
+ return NULL;
+
+ HICON hIcon = (HICON) CallService(MS_SKIN2_GETICON, 0, (LPARAM) iconName);
+ if (copy)
+ {
+ hIcon = CopyIcon(hIcon);
+ CallService(MS_SKIN2_RELEASEICON, 0, (LPARAM) iconName);
+ }
+ return hIcon;
+}
+
+
+void ReleaseIconEx(HICON hIcon)
+{
+ if (ServiceExists(MS_SKIN2_RELEASEICON))
+ CallService(MS_SKIN2_RELEASEICON, (WPARAM) hIcon, 0);
+ else
+ DestroyIcon(hIcon);
+}
diff --git a/Plugins/utils/mir_icons.h b/Plugins/utils/mir_icons.h
new file mode 100644
index 0000000..c61c7c6
--- /dev/null
+++ b/Plugins/utils/mir_icons.h
@@ -0,0 +1,33 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __MIR_ICONS_H__
+# define __MIR_ICONS_H__
+
+#include <windows.h>
+
+
+HICON LoadIconEx(const char *iconName, BOOL copy = FALSE);
+void ReleaseIconEx(HICON hIcon);
+
+
+
+
+#endif // __MIR_MEMORY_H__
diff --git a/Plugins/utils/mir_log.cpp b/Plugins/utils/mir_log.cpp
new file mode 100644
index 0000000..b842bb1
--- /dev/null
+++ b/Plugins/utils/mir_log.cpp
@@ -0,0 +1,133 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "mir_log.h"
+
+#include <stdio.h>
+
+extern "C"
+{
+#include <newpluginapi.h>
+#include <m_netlib.h>
+#include <m_protocols.h>
+#include <m_clist.h>
+}
+
+
+int mlog(const char *module, const char *function, const char *fmt, ...)
+{
+#ifdef ENABLE_LOG
+
+ va_list va;
+ char text[1024];
+ size_t len;
+
+ mir_snprintf(text, sizeof(text) - 10, "[%08u - %08u] [%s] [%s] ",
+ GetCurrentThreadId(), GetTickCount(), module, function);
+ len = strlen(text);
+
+ va_start(va, fmt);
+ mir_vsnprintf(&text[len], sizeof(text) - len, fmt, va);
+ va_end(va);
+
+#ifdef LOG_TO_NETLIB
+
+ return CallService(MS_NETLIB_LOG, NULL, (LPARAM) text);
+
+#else
+ char file[256];
+ _snprintf(file, sizeof(file), "c:\\miranda_%s.log.txt", module);
+
+ FILE *fp = fopen(file,"at");
+
+ if (fp != NULL)
+ {
+ fprintf(fp, "%s\n", text);
+ fclose(fp);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+
+#endif
+
+#else
+
+ return 0;
+
+#endif
+}
+
+int mlogC(const char *module, const char *function, HANDLE hContact, const char *fmt, ...)
+{
+#ifdef ENABLE_LOG
+
+ va_list va;
+ char text[1024];
+ size_t len;
+
+ char *name = NULL;
+ char *proto = NULL;
+ if (hContact != NULL)
+ {
+ name = (char*) CallService(MS_CLIST_GETCONTACTDISPLAYNAME, (WPARAM)hContact, 0);
+ proto = (char*) CallService(MS_PROTO_GETCONTACTBASEPROTO, (WPARAM)hContact, 0);
+ }
+
+ mir_snprintf(text, sizeof(text) - 10, "[%08u - %08u] [%s] [%s] [%08d - %s - %s] ",
+ GetCurrentThreadId(), GetTickCount(), module, function,
+ hContact, proto == NULL ? "" : proto, name == NULL ? "" : name);
+ len = strlen(text);
+
+ va_start(va, fmt);
+ mir_vsnprintf(&text[len], sizeof(text) - len, fmt, va);
+ va_end(va);
+
+#ifdef LOG_TO_NETLIB
+
+ return CallService(MS_NETLIB_LOG, NULL, (LPARAM) text);
+
+#else
+ char file[256];
+ _snprintf(file, sizeof(file), "c:\\miranda_%s.log.txt", module);
+
+ FILE *fp = fopen(file,"at");
+
+ if (fp != NULL)
+ {
+ fprintf(fp, "%s\n", text);
+ fclose(fp);
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+
+#endif
+
+#else
+
+ return 0;
+
+#endif
+}
diff --git a/Plugins/utils/mir_log.h b/Plugins/utils/mir_log.h
new file mode 100644
index 0000000..395c7e1
--- /dev/null
+++ b/Plugins/utils/mir_log.h
@@ -0,0 +1,41 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __LOG_H__
+# define __LOG_H__
+
+#include <windows.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+int mlog(const char *module, const char *function, const char *fmt, ...);
+int mlogC(const char *module, const char *function, HANDLE hContact, const char *fmt, ...);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __LOG_H__
diff --git a/Plugins/utils/mir_memory.cpp b/Plugins/utils/mir_memory.cpp
new file mode 100644
index 0000000..cea960b
--- /dev/null
+++ b/Plugins/utils/mir_memory.cpp
@@ -0,0 +1,70 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "mir_memory.h"
+
+#define MIRANDA_VER 0x0700
+#include <newpluginapi.h>
+#include <m_system.h>
+
+
+struct MM_INTERFACE mmi;
+struct UTF8_INTERFACE utfi;
+
+void init_mir_malloc()
+{
+ mir_getMMI(&mmi);
+ mir_getUTFI(&utfi);
+}
+
+
+void * mir_alloc0(size_t size)
+{
+ void * ptr = mir_alloc(size);
+
+ if (ptr != NULL)
+ memset(ptr, 0, size);
+
+ return ptr;
+}
+
+int strcmpnull(char *str1, char *str2)
+{
+ if ( str1 == NULL && str2 == NULL )
+ return 0;
+ if ( str1 != NULL && str2 == NULL )
+ return 1;
+ if ( str1 == NULL && str2 != NULL )
+ return -1;
+
+ return strcmp(str1, str2);
+}
+
+int strcmpnullW(WCHAR *str1, WCHAR *str2)
+{
+ if ( str1 == NULL && str2 == NULL )
+ return 0;
+ if ( str1 != NULL && str2 == NULL )
+ return 1;
+ if ( str1 == NULL && str2 != NULL )
+ return -1;
+
+ return lstrcmpW(str1, str2);
+}
diff --git a/Plugins/utils/mir_memory.h b/Plugins/utils/mir_memory.h
new file mode 100644
index 0000000..ef2a0d4
--- /dev/null
+++ b/Plugins/utils/mir_memory.h
@@ -0,0 +1,68 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __MIR_MEMORY_H__
+# define __MIR_MEMORY_H__
+
+#include <windows.h>
+
+
+// Need to be called on ME_SYSTEM_MODULESLOADED or Load
+void init_mir_malloc();
+
+
+void * mir_alloc0(size_t size);
+int strcmpnull(char *str1, char *str2);
+int strcmpnullW(WCHAR *str1, WCHAR *str2);
+
+
+#ifdef _UNICODE
+
+# define lstrcmpnull strcmpnullW
+
+#define INPLACE_CHAR_TO_TCHAR(_new_var_, _size_, _old_var_) \
+ TCHAR _new_var_[_size_]; \
+ MultiByteToWideChar(CP_ACP, 0, _old_var_, -1, _new_var_, _size_)
+
+
+#define INPLACE_TCHAR_TO_CHAR(_new_var_, _size_, _old_var_) \
+ char _new_var_[_size_]; \
+ WideCharToMultiByte(CP_ACP, 0, _old_var_, -1, _new_var_, _size_, NULL, NULL);
+
+#else
+
+# define lstrcmpnull strcmpnull
+
+#define INPLACE_CHAR_TO_TCHAR(_new_var_, _size_, _old_var_) \
+ TCHAR *_new_var_ = _old_var_
+
+#define INPLACE_TCHAR_TO_CHAR(_new_var_, _size_, _old_var_) \
+ char *_new_var_ = _old_var_;
+
+#endif
+
+
+
+// Free memory and set to NULL
+//#define MIR_FREE(_x_) if (_x_ != NULL) { mir_free(_x_); _x_ = NULL; }
+
+
+
+#endif // __MIR_MEMORY_H__
diff --git a/Plugins/utils/mir_options.cpp b/Plugins/utils/mir_options.cpp
new file mode 100644
index 0000000..bf4e3f0
--- /dev/null
+++ b/Plugins/utils/mir_options.cpp
@@ -0,0 +1,541 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#include "mir_options.h"
+#include "mir_memory.h"
+
+#include <commctrl.h>
+#include <stdio.h>
+#include <tchar.h>
+
+#define MIRANDA_VER 0x0600
+#include <newpluginapi.h>
+#include <m_database.h>
+#include <m_utils.h>
+#include <m_langpack.h>
+#include <m_protocols.h>
+#include <m_protosvc.h>
+#include <m_system.h>
+
+
+#define MAX_REGS(_A_) ( sizeof(_A_) / sizeof(_A_[0]) )
+
+
+static TCHAR* MyDBGetContactSettingTString(HANDLE hContact, char* module, char* setting, TCHAR* out, size_t len, TCHAR *def)
+{
+ DBVARIANT dbv;
+
+ out[0] = _T('\0');
+
+ if (!DBGetContactSettingTString(hContact, module, setting, &dbv))
+ {
+#ifdef UNICODE
+ if (dbv.type == DBVT_ASCIIZ)
+ {
+ MultiByteToWideChar(CP_ACP, 0, dbv.pszVal, -1, out, len);
+ }
+ else if (dbv.type == DBVT_UTF8)
+ {
+ MultiByteToWideChar(CP_UTF8, 0, dbv.pszVal, -1, out, len);
+ }
+ else if (dbv.type == DBVT_WCHAR)
+ {
+ lstrcpyn(out, dbv.pwszVal, len);
+ }
+#else
+ if (dbv.type == DBVT_ASCIIZ)
+ {
+ lstrcpyn(out, dbv.pszVal, len);
+ }
+#endif
+ else
+ {
+ if (def != NULL)
+ lstrcpyn(out, def, len);
+ }
+
+ DBFreeVariant(&dbv);
+ }
+ else
+ {
+ if (def != NULL)
+ lstrcpyn(out, def, len);
+ }
+
+ return out;
+}
+
+
+static TCHAR dbPath[MAX_PATH] = {0}; // database profile path (read at startup only)
+
+
+static int PathIsAbsolute(const TCHAR *path)
+{
+ if (!path || !(lstrlen(path) > 2))
+ return 0;
+ if ((path[1]==_T(':') && path[2]==_T('\\')) || (path[0]==_T('\\')&&path[1]==_T('\\')))
+ return 1;
+ return 0;
+}
+
+static void PathToRelative(TCHAR *pOut, size_t outSize, const TCHAR *pSrc)
+{
+ if (!PathIsAbsolute(pSrc))
+ {
+ lstrcpyn(pOut, pSrc, outSize);
+ }
+ else
+ {
+ if (dbPath[0] == _T('\0'))
+ {
+ char tmp[1024];
+ CallService(MS_DB_GETPROFILEPATH, MAX_REGS(tmp), (LPARAM) tmp);
+ mir_sntprintf(dbPath, MAX_REGS(dbPath), _T(TCHAR_STR_PARAM) _T("\\"), tmp);
+ }
+
+ size_t len = lstrlen(dbPath);
+ if (_tcsnicmp(pSrc, dbPath, len))
+ {
+ mir_sntprintf(pOut, outSize, _T("%s"), pSrc + len);
+ }
+ else
+ {
+ lstrcpyn(pOut, pSrc, outSize);
+ }
+ }
+}
+
+static void PathToAbsolute(TCHAR *pOut, size_t outSize, const TCHAR *pSrc)
+{
+ if (PathIsAbsolute(pSrc) || !isalnum(pSrc[0]))
+ {
+ lstrcpyn(pOut, pSrc, outSize);
+ }
+ else
+ {
+ if (dbPath[0] == _T('\0'))
+ {
+ char tmp[1024];
+ CallService(MS_DB_GETPROFILEPATH, MAX_REGS(tmp), (LPARAM) tmp);
+ mir_sntprintf(dbPath, MAX_REGS(dbPath), _T(TCHAR_STR_PARAM) _T("\\"), tmp);
+ }
+
+ mir_sntprintf(pOut, outSize, _T("%s%s"), dbPath, pSrc);
+ }
+}
+
+
+void LoadOpts(OptPageControl *controls, int controlsSize, char *module)
+{
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ OptPageControl *ctrl = &controls[i];
+
+ if (ctrl->var != NULL)
+ {
+ switch(ctrl->type)
+ {
+ case CONTROL_CHECKBOX:
+ {
+ *((BYTE *) ctrl->var) = DBGetContactSettingByte(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_SPIN:
+ {
+ *((WORD *) ctrl->var) = DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_COLOR:
+ {
+ *((COLORREF *) ctrl->var) = (COLORREF) DBGetContactSettingDword(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_RADIO:
+ {
+ *((WORD *) ctrl->var) = DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_COMBO:
+ {
+ *((WORD *) ctrl->var) = DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue);
+ break;
+ }
+ case CONTROL_PROTOCOL_LIST:
+ {
+ break;
+ }
+ case CONTROL_TEXT:
+ {
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, ((TCHAR *) ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
+ break;
+ }
+ case CONTROL_FILE:
+ {
+ TCHAR tmp[1024];
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : ctrl->tszDefValue);
+ PathToAbsolute(((TCHAR *) ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), tmp);
+ break;
+ }
+ case CONTROL_COMBO_TEXT:
+ case CONTROL_COMBO_ITEMDATA:
+ {
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, ((TCHAR *) ctrl->var), min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+
+BOOL CALLBACK SaveOptsDlgProc(OptPageControl *controls, int controlsSize, char *module, HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ {
+ TranslateDialogDefault(hwndDlg);
+
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ OptPageControl *ctrl = &controls[i];
+
+ if (GetDlgItem(hwndDlg, ctrl->nID) == NULL)
+ continue;
+
+ switch(ctrl->type)
+ {
+ case CONTROL_CHECKBOX:
+ {
+ CheckDlgButton(hwndDlg, ctrl->nID, DBGetContactSettingByte(NULL, module, ctrl->setting, ctrl->dwDefValue) == 1 ? BST_CHECKED : BST_UNCHECKED);
+ break;
+ }
+ case CONTROL_SPIN:
+ {
+ SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_SETBUDDY, (WPARAM)GetDlgItem(hwndDlg, ctrl->nID),0);
+ SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_SETRANGE, 0, MAKELONG(ctrl->max, ctrl->min));
+ SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_SETPOS,0, MAKELONG(DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue), 0));
+ break;
+ }
+ case CONTROL_COLOR:
+ {
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CPM_SETCOLOUR, 0, (COLORREF) DBGetContactSettingDword(NULL, module, ctrl->setting, ctrl->dwDefValue));
+ break;
+ }
+ case CONTROL_RADIO:
+ {
+ CheckDlgButton(hwndDlg, ctrl->nID, DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue) == ctrl->value ? BST_CHECKED : BST_UNCHECKED);
+ break;
+ }
+ case CONTROL_COMBO:
+ {
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CB_SETCURSEL, DBGetContactSettingWord(NULL, module, ctrl->setting, ctrl->dwDefValue), 0);
+ break;
+ }
+ case CONTROL_PROTOCOL_LIST:
+ {
+ // Fill list view
+ HWND hwndProtocols = GetDlgItem(hwndDlg, ctrl->nID);
+ LVCOLUMN lvc;
+ LVITEM lvi;
+ PROTOCOLDESCRIPTOR **protos;
+ int i,count;
+ char szName[128];
+
+ ListView_SetExtendedListViewStyle(hwndProtocols, LVS_EX_CHECKBOXES);
+
+ ZeroMemory(&lvc, sizeof(lvc));
+ lvc.mask = LVCF_FMT;
+ lvc.fmt = LVCFMT_IMAGE | LVCFMT_LEFT;
+ ListView_InsertColumn(hwndProtocols, 0, &lvc);
+
+ ZeroMemory(&lvi, sizeof(lvi));
+ lvi.mask = LVIF_TEXT | LVIF_PARAM;
+ lvi.iSubItem = 0;
+ lvi.iItem = 1000;
+
+ CallService(MS_PROTO_ENUMPROTOCOLS, (WPARAM)&count, (LPARAM)&protos);
+
+ for (i = 0; i < count; i++)
+ {
+ if (protos[i]->type != PROTOTYPE_PROTOCOL)
+ continue;
+
+ if (protos[i]->szName == NULL || protos[i]->szName[0] == '\0')
+ continue;
+
+ if (ctrl->allowProtocol != NULL && !ctrl->allowProtocol(protos[i]->szName))
+ continue;
+
+ CallProtoService(protos[i]->szName, PS_GETNAME, sizeof(szName), (LPARAM)szName);
+
+ char *setting = (char *) mir_alloc0(128 * sizeof(char));
+ mir_snprintf(setting, 128, ctrl->setting, protos[i]->szName);
+
+ BOOL show = (BOOL)DBGetContactSettingByte(NULL, module, setting, ctrl->dwDefValue);
+
+ lvi.lParam = (LPARAM)setting;
+#ifdef UNICODE
+ WCHAR szwName[128];
+ MultiByteToWideChar(CP_ACP, 0, szName, -1, szwName, 128);
+ lvi.pszText = TranslateTS(szwName);
+#else
+ lvi.pszText = TranslateTS(szName);
+#endif
+ lvi.iItem = ListView_InsertItem(hwndProtocols, &lvi);
+ ListView_SetItemState(hwndProtocols, lvi.iItem, INDEXTOSTATEIMAGEMASK(show?2:1), LVIS_STATEIMAGEMASK);
+ }
+
+ ListView_SetColumnWidth(hwndProtocols, 0, LVSCW_AUTOSIZE);
+ ListView_Arrange(hwndProtocols, LVA_ALIGNLEFT | LVA_ALIGNTOP);
+ break;
+ }
+ case CONTROL_TEXT:
+ {
+ TCHAR tmp[1024];
+ SetDlgItemText(hwndDlg, ctrl->nID, MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue)));
+ SendDlgItemMessage(hwndDlg, ctrl->nID, EM_LIMITTEXT, min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), 0);
+ break;
+ }
+ case CONTROL_FILE:
+ {
+ TCHAR tmp[1024];
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : ctrl->tszDefValue);
+ TCHAR abs[1024];
+ PathToAbsolute(abs, 1024, tmp);
+
+ SetDlgItemText(hwndDlg, ctrl->nID, abs);
+ SendDlgItemMessage(hwndDlg, ctrl->nID, EM_LIMITTEXT, min(ctrl->max <= 0 ? 1024 : ctrl->max, 1024), 0);
+ break;
+ }
+ case CONTROL_COMBO_TEXT:
+ {
+ TCHAR tmp[1024];
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CB_SELECTSTRING, 0, (WPARAM) tmp);
+ break;
+ }
+ case CONTROL_COMBO_ITEMDATA:
+ {
+ TCHAR tmp[1024];
+ MyDBGetContactSettingTString(NULL, module, ctrl->setting, tmp, 1024, ctrl->tszDefValue == NULL ? NULL : TranslateTS(ctrl->tszDefValue));
+ int count = SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETCOUNT, 0, 0);
+ int i;
+ for(i = 0; i < count; i++)
+ {
+ TCHAR *id = (TCHAR *) SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETITEMDATA, (WPARAM) i, 0);
+ if (lstrcmp(id, tmp) == 0)
+ break;
+ }
+ if (i < count)
+ SendDlgItemMessage(hwndDlg, ctrl->nID, CB_SETCURSEL, i, 0);
+ break;
+ }
+ }
+ }
+ break;
+ }
+ case WM_COMMAND:
+ {
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ OptPageControl *ctrl = &controls[i];
+
+ if (LOWORD(wParam) == ctrl->nID)
+ {
+ switch(ctrl->type)
+ {
+ case CONTROL_TEXT:
+ case CONTROL_SPIN:
+ {
+ // Don't make apply enabled during buddy set
+ if (HIWORD(wParam) != EN_CHANGE || (HWND)lParam != GetFocus())
+ return 0;
+
+ break;
+ }
+ case CONTROL_COMBO_ITEMDATA:
+ case CONTROL_COMBO_TEXT:
+ case CONTROL_COMBO:
+ {
+ if (HIWORD(wParam) != CBN_SELCHANGE || (HWND)lParam != GetFocus())
+ return 0;
+
+ break;
+ }
+ }
+
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+ }
+ }
+
+ break;
+ }
+ case WM_NOTIFY:
+ {
+ LPNMHDR lpnmhdr = (LPNMHDR)lParam;
+
+ if (lpnmhdr->idFrom == 0 && lpnmhdr->code == PSN_APPLY)
+ {
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ OptPageControl *ctrl = &controls[i];
+
+ if (GetDlgItem(hwndDlg, ctrl->nID) == NULL)
+ continue;
+
+ switch(ctrl->type)
+ {
+ case CONTROL_CHECKBOX:
+ {
+ DBWriteContactSettingByte(NULL, module, ctrl->setting, (BYTE) IsDlgButtonChecked(hwndDlg, ctrl->nID));
+ break;
+ }
+ case CONTROL_SPIN:
+ {
+ DBWriteContactSettingWord(NULL, module, ctrl->setting, (WORD) SendDlgItemMessage(hwndDlg, ctrl->nIDSpin, UDM_GETPOS, 0, 0));
+ break;
+ }
+ case CONTROL_COLOR:
+ {
+ DBWriteContactSettingDword(NULL, module, ctrl->setting, (DWORD) SendDlgItemMessage(hwndDlg, ctrl->nID, CPM_GETCOLOUR, 0, 0));
+ break;
+ }
+ case CONTROL_RADIO:
+ {
+ if (IsDlgButtonChecked(hwndDlg, ctrl->nID))
+ DBWriteContactSettingWord(NULL, module, ctrl->setting, (BYTE) ctrl->value);
+ break;
+ }
+ case CONTROL_COMBO:
+ {
+ DBWriteContactSettingWord(NULL, module, ctrl->setting, (WORD) SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETCURSEL, 0, 0));
+ break;
+ }
+ case CONTROL_PROTOCOL_LIST:
+ {
+ LVITEM lvi = {0};
+ HWND hwndProtocols = GetDlgItem(hwndDlg, ctrl->nID);
+ int i;
+
+ lvi.mask = (UINT) LVIF_PARAM;
+
+ for (i = 0; i < ListView_GetItemCount(hwndProtocols); i++)
+ {
+ lvi.iItem = i;
+ ListView_GetItem(hwndProtocols, &lvi);
+
+ char *setting = (char *)lvi.lParam;
+ DBWriteContactSettingByte(NULL, module, setting, (BYTE)ListView_GetCheckState(hwndProtocols, i));
+ }
+ break;
+ }
+ case CONTROL_TEXT:
+ {
+ TCHAR tmp[1024];
+ GetDlgItemText(hwndDlg, ctrl->nID, tmp, 1024);
+ DBWriteContactSettingTString(NULL, module, ctrl->setting, tmp);
+ break;
+ }
+ case CONTROL_FILE:
+ {
+ TCHAR tmp[1024];
+ GetDlgItemText(hwndDlg, ctrl->nID, tmp, 1024);
+ TCHAR rel[1024];
+ PathToRelative(rel, 1024, tmp);
+ DBWriteContactSettingTString(NULL, module, ctrl->setting, rel);
+ break;
+ }
+ case CONTROL_COMBO_TEXT:
+ {
+ TCHAR tmp[1024];
+ GetDlgItemText(hwndDlg, ctrl->nID, tmp, 1024);
+ DBWriteContactSettingTString(NULL, module, ctrl->setting, tmp);
+ break;
+ }
+ case CONTROL_COMBO_ITEMDATA:
+ {
+ int sel = SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETCURSEL, 0, 0);
+ DBWriteContactSettingTString(NULL, module, ctrl->setting, (TCHAR *) SendDlgItemMessage(hwndDlg, ctrl->nID, CB_GETITEMDATA, (WPARAM) sel, 0));
+ break;
+ }
+ }
+ }
+
+ LoadOpts(controls, controlsSize, module);
+
+ return TRUE;
+ }
+ else if (lpnmhdr->idFrom != 0 && lpnmhdr->code == LVN_ITEMCHANGED)
+ {
+ // Changed for protocols
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ OptPageControl *ctrl = &controls[i];
+
+ if (ctrl->type == CONTROL_PROTOCOL_LIST && ctrl->nID == lpnmhdr->idFrom)
+ {
+ NMLISTVIEW *nmlv = (NMLISTVIEW *)lParam;
+
+ if(IsWindowVisible(GetDlgItem(hwndDlg, ctrl->nID)) && ((nmlv->uNewState ^ nmlv->uOldState) & LVIS_STATEIMAGEMASK))
+ SendMessage(GetParent(hwndDlg), PSM_CHANGED, 0, 0);
+
+ break;
+ }
+ }
+ }
+ break;
+ }
+ case WM_DESTROY:
+ {
+ for (int i = 0 ; i < controlsSize ; i++)
+ {
+ OptPageControl *ctrl = &controls[i];
+
+ if (GetDlgItem(hwndDlg, ctrl->nID) == NULL)
+ continue;
+
+ switch(ctrl->type)
+ {
+ case CONTROL_PROTOCOL_LIST:
+ {
+ LVITEM lvi = {0};
+ HWND hwndProtocols = GetDlgItem(hwndDlg, ctrl->nID);
+ int i;
+
+ lvi.mask = (UINT) LVIF_PARAM;
+
+ for (i = 0; i < ListView_GetItemCount(hwndProtocols); i++)
+ {
+ lvi.iItem = i;
+ ListView_GetItem(hwndProtocols, &lvi);
+ mir_free((char *) lvi.lParam);
+ }
+ break;
+ }
+ }
+ }
+ break;
+ }
+ }
+
+ return 0;
+}
diff --git a/Plugins/utils/mir_options.h b/Plugins/utils/mir_options.h
new file mode 100644
index 0000000..2c433df
--- /dev/null
+++ b/Plugins/utils/mir_options.h
@@ -0,0 +1,68 @@
+/*
+Copyright (C) 2005 Ricardo Pescuma Domenecci
+
+This is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this file; see the file license.txt. If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.
+*/
+
+
+#ifndef __MIR_OPTIONS_H__
+# define __MIR_OPTIONS_H__
+
+#include <windows.h>
+
+
+#define CONTROL_CHECKBOX 0 // Stored as BYTE
+#define CONTROL_SPIN 1 // Stored as WORD
+#define CONTROL_COLOR 2 // Stored as DWORD
+#define CONTROL_RADIO 3 // Stored as WORD
+#define CONTROL_COMBO 4 // Stored as WORD
+#define CONTROL_PROTOCOL_LIST 5 // Stored as BYTEs
+#define CONTROL_TEXT 6 // Stored as TCHARs, max len 1024
+#define CONTROL_COMBO_TEXT 7 // Stored as TCHARs, max len 1024
+#define CONTROL_COMBO_ITEMDATA 8 // Stored as TCHARs, max len 1024
+#define CONTROL_FILE 9 // Stored as TCHARs, max len 1024
+
+
+typedef BOOL (* FPAllowProtocol) (const char *proto);
+
+typedef struct {
+ void *var;
+ int type;
+ unsigned int nID;
+ char *setting;
+ union {
+ DWORD dwDefValue;
+ TCHAR *tszDefValue;
+ };
+ union {
+ int nIDSpin;
+ int value;
+ FPAllowProtocol allowProtocol;
+ };
+ WORD min;
+ WORD max;
+} OptPageControl;
+
+BOOL CALLBACK SaveOptsDlgProc(OptPageControl *controls, int controlsSize, char *module, HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
+
+void LoadOpts(OptPageControl *controls, int controlsSize, char *module);
+
+
+
+
+
+
+#endif // __MIR_OPTIONS_H__