summaryrefslogtreecommitdiff
path: root/plugins/CountryFlags
diff options
context:
space:
mode:
authorKirill Volinsky <mataes2007@gmail.com>2012-05-17 17:37:22 +0000
committerKirill Volinsky <mataes2007@gmail.com>2012-05-17 17:37:22 +0000
commit78d71d2cad6f243c6ff31d41380b8c5b58407de5 (patch)
treed0c05983b315352c5e66d23420da4b8fd8b5aff4 /plugins/CountryFlags
parenta9e8daee448c229aa3f8ded0c5f5c0fe7aa42529 (diff)
added some plugins
git-svn-id: http://svn.miranda-ng.org/main/trunk@20 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/CountryFlags')
-rw-r--r--plugins/CountryFlags/Info_Src.txt32
-rw-r--r--plugins/CountryFlags/License_Appendix.txt64
-rw-r--r--plugins/CountryFlags/countrylistext.c345
-rw-r--r--plugins/CountryFlags/docs/Flags-Developer.txt48
-rw-r--r--plugins/CountryFlags/docs/Flags-License.txt278
-rw-r--r--plugins/CountryFlags/docs/Flags-Readme.txt140
-rw-r--r--plugins/CountryFlags/docs/Flags-Translation.txt74
-rw-r--r--plugins/CountryFlags/extraimg.c495
-rw-r--r--plugins/CountryFlags/flags.def11
-rw-r--r--plugins/CountryFlags/flags.h89
-rw-r--r--plugins/CountryFlags/flags.sln29
-rw-r--r--plugins/CountryFlags/flags.vcxproj408
-rw-r--r--plugins/CountryFlags/flags.vcxproj.filters138
-rw-r--r--plugins/CountryFlags/huffman.c506
-rw-r--r--plugins/CountryFlags/icons.c284
-rw-r--r--plugins/CountryFlags/ip2country.c327
-rw-r--r--plugins/CountryFlags/main.c163
-rw-r--r--plugins/CountryFlags/res/flags.bmpbin0 -> 122022 bytes
-rw-r--r--plugins/CountryFlags/res/ip-to-country.binbin0 -> 647987 bytes
-rw-r--r--plugins/CountryFlags/resource.h25
-rw-r--r--plugins/CountryFlags/resource.rc128
-rw-r--r--plugins/CountryFlags/utils.c162
-rw-r--r--plugins/CountryFlags/version.h38
-rw-r--r--plugins/CountryFlags/version.rc47
24 files changed, 3831 insertions, 0 deletions
diff --git a/plugins/CountryFlags/Info_Src.txt b/plugins/CountryFlags/Info_Src.txt
new file mode 100644
index 0000000000..5c1b19be88
--- /dev/null
+++ b/plugins/CountryFlags/Info_Src.txt
@@ -0,0 +1,32 @@
+
+Country Flags Plugin 0.1.0.3 for Miranda IM 0.7+
+------------------------------------------------------------------------
+ Source Code
+
+Reminder:
+'Country Flags' is released under the terms of the
+GNU General Public License.
+See 'Flags-License.txt' for more details.
+'Country Flags' is copyright 2006-2007 by H. Herkenrath.
+
+Please notify me of any changes that improve
+'Country Flags' or add new features.
+If you have any questions on the code, feel free
+to contact me at my email address.
+
+ H. Herkenrath (hrathh at users.sourceforge.net)
+
+
+Notes
+------------------------------------------------------------------------
+The following files need to be changed to bump the version number:
+
+Info_Src.txt (1 place)
+version.h (4 places)
+m_flags.h (1 place)
+m_flags.inc (1 place)
+docs\Flags-Readme.txt (3 places)
+docs\Flags-Translation.txt (2 or 3 places)
+docs\Flags-Developer.txt (1 place)
+
+
diff --git a/plugins/CountryFlags/License_Appendix.txt b/plugins/CountryFlags/License_Appendix.txt
new file mode 100644
index 0000000000..c590c3f5fb
--- /dev/null
+++ b/plugins/CountryFlags/License_Appendix.txt
@@ -0,0 +1,64 @@
+
+Excecpt of GNU General Public License (Appendix):
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/plugins/CountryFlags/countrylistext.c b/plugins/CountryFlags/countrylistext.c
new file mode 100644
index 0000000000..50978fdb97
--- /dev/null
+++ b/plugins/CountryFlags/countrylistext.c
@@ -0,0 +1,345 @@
+/*
+Miranda IM Country Flags Plugin
+Copyright (C) 2006-2007 H. Herkenrath
+
+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 (Flags-License.txt); if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "flags.h"
+
+static HANDLE hServiceGetList,hServiceGetByNumber;
+
+/************************* Services *******************************/
+
+static struct CountryListEntry countries[]={
+ {0 ,"Unspecified"},
+ {9999,"Other"},
+ {0xFFFF,"Unknown"},
+ {93 ,"Afghanistan"},
+ {355 ,"Albania"},
+ {213 ,"Algeria"},
+ {684 ,"American Samoa"},
+ {376 ,"Andorra"},
+ {244 ,"Angola"},
+ {101 ,"Anguilla"},
+ {102 ,"Antigua and Barbuda"},
+ //{5902,"Antilles"}, /* removed */
+ {54 ,"Argentina"},
+ {374 ,"Armenia"},
+ {297 ,"Aruba"},
+ {247 ,"Ascension Island"},
+ {61 ,"Australia"},
+ {6721,"Australian Antarctic Territory"}, /* was missing */
+ {43 ,"Austria"},
+ {994 ,"Azerbaijan"},
+ {103 ,"Bahamas"},
+ {973 ,"Bahrain"},
+ {880 ,"Bangladesh"},
+ {104 ,"Barbados"},
+ {120 ,"Barbuda"},
+ {375 ,"Belarus"},
+ {32 ,"Belgium"},
+ {501 ,"Belize"},
+ {229 ,"Benin"},
+ {105 ,"Bermuda"},
+ {975 ,"Bhutan"},
+ {591 ,"Bolivia"},
+ {387 ,"Bosnia and Herzegovina"},
+ {267 ,"Botswana"},
+ {55 ,"Brazil"},
+ {106 ,"British Virgin Islands"},
+ {673 ,"Brunei"},
+ {359 ,"Bulgaria"},
+ {226 ,"Burkina Faso"},
+ {257 ,"Burundi"},
+ {855 ,"Cambodia"},
+ {237 ,"Cameroon"},
+ {107 ,"Canada"},
+ {178 ,"Canary Islands"},
+ {238 ,"Cape Verde Islands"},
+ {108 ,"Cayman Islands"},
+ {236 ,"Central African Republic"},
+ {235 ,"Chad"},
+ {56 ,"Chile, Republic of"},
+ {86 ,"China"},
+ {672 ,"Christmas Island"},
+ {6101,"Cocos-Keeling Islands"},
+ //{6102,"Cocos (Keeling) Islands"}, /* removed */
+ {57 ,"Colombia"},
+ {2691,"Comoros"},
+ {243 ,"Congo, Democratic Republic of (Zaire)"},
+ {242 ,"Congo, Republic of the"},
+ {682 ,"Cook Islands"},
+ {506 ,"Costa Rica"},
+ {225 ,"Cote d'Ivoire (Ivory Coast)"},
+ {385 ,"Croatia"},
+ {53 ,"Cuba"},
+ {357 ,"Cyprus"},
+ {420 ,"Czech Republic"},
+ {45 ,"Denmark"},
+ {246 ,"Diego Garcia"},
+ {253 ,"Djibouti"},
+ {109 ,"Dominica"},
+ {110 ,"Dominican Republic"},
+ {593 ,"Ecuador"},
+ {20 ,"Egypt"},
+ {503 ,"El Salvador"},
+ {240 ,"Equatorial Guinea"},
+ {291 ,"Eritrea"},
+ {372 ,"Estonia"},
+ {251 ,"Ethiopia"},
+ {500 ,"Falkland Islands (Malvinas)"}, /* was "Falkland Islands" */
+ {298 ,"Faroe Islands"}, /* was "Faeroe Islands" */
+ {679 ,"Fiji"},
+ {358 ,"Finland"},
+ {33 ,"France"},
+ {5901,"French Antilles"},
+ {594 ,"French Guiana"},
+ {689 ,"French Polynesia"},
+ {241 ,"Gabon"},
+ {220 ,"Gambia"},
+ {995 ,"Georgia"},
+ {49 ,"Germany"},
+ {233 ,"Ghana"},
+ {350 ,"Gibraltar"},
+ {30 ,"Greece"},
+ {299 ,"Greenland"},
+ {111 ,"Grenada"},
+ {590 ,"Guadeloupe"},
+ {671 ,"Guam, US Territory of"},
+ {5399,"Guantanamo Bay"}, /* was missing */
+ {502 ,"Guatemala"},
+ {224 ,"Guinea"},
+ {245 ,"Guinea-Bissau"},
+ {592 ,"Guyana"},
+ {509 ,"Haiti"},
+ {504 ,"Honduras"},
+ {852 ,"Hong Kong"},
+ {36 ,"Hungary"},
+ {354 ,"Iceland"},
+ {91 ,"India"},
+ {62 ,"Indonesia"},
+ {98 ,"Iran (Islamic Republic of)"},
+ {964 ,"Iraq"},
+ {353 ,"Ireland"},
+ {972 ,"Israel"},
+ {39 ,"Italy"},
+ {112 ,"Jamaica"},
+ {81 ,"Japan"},
+ {962 ,"Jordan"},
+ {705 ,"Kazakhstan"},
+ {254 ,"Kenya"},
+ {686 ,"Kiribati"},
+ {850 ,"Korea, North"},
+ {82 ,"Korea, South"},
+ {965 ,"Kuwait"},
+ {706 ,"Kyrgyzstan"},
+ {856 ,"Laos"},
+ {371 ,"Latvia"},
+ {961 ,"Lebanon"},
+ {266 ,"Lesotho"},
+ {231 ,"Liberia"},
+ {218 ,"Libyan Arab Jamahiriya"},
+ {4101,"Liechtenstein"},
+ {370 ,"Lithuania"},
+ {352 ,"Luxembourg"},
+ {853 ,"Macau"},
+ {389 ,"Macedonia (F.Y.R.O.M.)"},
+ {261 ,"Madagascar"},
+ {265 ,"Malawi"},
+ {60 ,"Malaysia"},
+ {960 ,"Maldives"},
+ {223 ,"Mali"},
+ {356 ,"Malta"},
+ {692 ,"Marshall Islands"},
+ {596 ,"Martinique"},
+ {222 ,"Mauritania"},
+ {230 ,"Mauritius"},
+ {269 ,"Mayotte Island"},
+ {52 ,"Mexico"},
+ {691 ,"Micronesia, Federated States of"},
+ {373 ,"Moldova, Republic of"},
+ {377 ,"Monaco"},
+ {976 ,"Mongolia"},
+ {382 ,"Montenegro, Republic of"}, /* was "Yugoslavia - Montenegro" */
+ {113 ,"Montserrat"},
+ {212 ,"Morocco"},
+ {258 ,"Mozambique"},
+ {95 ,"Myanmar"},
+ {264 ,"Namibia"},
+ {674 ,"Nauru"},
+ {977 ,"Nepal"},
+ {31 ,"Netherlands"},
+ {599 ,"Netherlands Antilles"},
+ {114 ,"Nevis"},
+ {687 ,"New Caledonia"},
+ {64 ,"New Zealand"},
+ {505 ,"Nicaragua"},
+ {227 ,"Niger"},
+ {234 ,"Nigeria"},
+ {683 ,"Niue"},
+ {6722,"Norfolk Island"},
+ {47 ,"Norway"},
+ {968 ,"Oman"},
+ {92 ,"Pakistan"},
+ {680 ,"Palau"},
+ {507 ,"Panama"},
+ {675 ,"Papua New Guinea"},
+ {595 ,"Paraguay"},
+ {51 ,"Peru"},
+ {63 ,"Philippines"},
+ {48 ,"Poland"},
+ {351 ,"Portugal"},
+ {121 ,"Puerto Rico"},
+ {974 ,"Qatar"},
+ {262 ,"Reunion Island"},
+ {40 ,"Romania"},
+ {6701,"Rota Island"},
+ {7 ,"Russia"},
+ {250 ,"Rwanda"},
+ {290 ,"Saint Helena"},
+ {115 ,"Saint Kitts"},
+ {1141,"Saint Kitts and Nevis"},
+ {122 ,"Saint Lucia"},
+ {508 ,"Saint Pierre and Miquelon"},
+ {116 ,"Saint Vincent and the Grenadines"},
+ {670 ,"Saipan Island (Northern Mariana Islands)"}, /* was "Saipan Island" */
+ {685 ,"Samoa"}, /* was "Western Samoa" */
+ {378 ,"San Marino"},
+ {239 ,"Sao Tome and Principe"},
+ {966 ,"Saudi Arabia"},
+ {442 ,"Scotland"},
+ {221 ,"Senegal"},
+ {381 ,"Serbia, Republic of"}, /* was "Yugoslavia" */
+ {248 ,"Seychelles"},
+ {232 ,"Sierra Leone"},
+ {65 ,"Singapore"},
+ {421 ,"Slovakia"},
+ {386 ,"Slovenia"},
+ {677 ,"Solomon Islands"},
+ {252 ,"Somalia"},
+ {27 ,"South Africa"},
+ {34 ,"Spain"},
+ {94 ,"Sri Lanka"},
+ {249 ,"Sudan"},
+ {597 ,"Suriname"},
+ {268 ,"Swaziland"},
+ {46 ,"Sweden"},
+ {41 ,"Switzerland"},
+ {963 ,"Syrian Arab Republic"},
+ {886 ,"Taiwan"},
+ {708 ,"Tajikistan"},
+ {255 ,"Tanzania"},
+ {66 ,"Thailand"},
+ {6702,"Tinian Island"},
+ {228 ,"Togo"},
+ {690 ,"Tokelau"},
+ {676 ,"Tonga"},
+ {117 ,"Trinidad and Tobago"},
+ {216 ,"Tunisia"},
+ {90 ,"Turkey"},
+ {709 ,"Turkmenistan"},
+ {118 ,"Turks and Caicos Islands"},
+ {688 ,"Tuvalu"},
+ {256 ,"Uganda"},
+ {380 ,"Ukraine"},
+ {971 ,"United Arab Emirates"},
+ {44 ,"United Kingdom"},
+ {598 ,"Uruguay"},
+ {1 ,"USA"},
+ {711 ,"Uzbekistan"},
+ {678 ,"Vanuatu"},
+ {379 ,"Vatican City"},
+ {58 ,"Venezuela"},
+ {84 ,"Vietnam"},
+ {123 ,"Virgin Islands (USA)"},
+ {441 ,"Wales"},
+ {681 ,"Wallis and Futuna Islands"},
+ {967 ,"Yemen"},
+ //{3811,"Yugoslavia - Serbia"}, /* removed */
+ {260 ,"Zambia"},
+ {263 ,"Zimbabwe"},
+};
+
+static int ServiceGetCountryByNumber(WPARAM wParam,LPARAM lParam)
+{
+ int i;
+ UNREFERENCED_PARAMETER(lParam);
+ for(i=0; i<SIZEOF(countries); ++i)
+ if((int)wParam==countries[i].id)
+ return (int)countries[i].szName;
+ return (int)(char*)NULL;
+}
+
+static int ServiceGetCountryList(WPARAM wParam,LPARAM lParam)
+{
+ if((int*)wParam==NULL || (void*)lParam==NULL) return 1;
+ *(int*)wParam=SIZEOF(countries);
+ *(struct CountryListEntry**)lParam=countries;
+ return 0;
+}
+
+/************************* Misc ***********************************/
+
+static DWORD NameHashFunction(const char *szStr)
+{
+#if defined _M_IX86 && !defined _NUMEGA_BC_FINALCHECK && !defined NOINLINEASM
+ __asm {
+ xor edx,edx
+ xor eax,eax
+ mov esi,szStr
+ mov al,[esi]
+ dec esi
+ xor cl,cl
+ lph_top: //only 4 of 9 instructions in here don't use AL, so optimal pipe use is impossible
+ xor edx,eax
+ inc esi
+ and cl,31
+ movzx eax,byte ptr [esi]
+ add cl,5
+ test al,al
+ rol eax,cl //rol is u-pipe only, but pairable
+ //rol doesn't touch z-flag
+ jnz lph_top //5 clock tick loop. not bad.
+
+ xor eax,edx
+ }
+#else
+ DWORD hash=0;
+ int i;
+ int shift=0;
+ for(i=0;szStr[i];i++) {
+ hash^=szStr[i]<<shift;
+ if (shift>24) hash^=(szStr[i]>>(32-shift))&0x7F;
+ shift=(shift+5)&0x1F;
+ }
+ return hash;
+#endif
+}
+
+void InitCountryListExt(void)
+{
+ /* hack to replace built-in country list */
+ DestroyServiceFunction((HANDLE)NameHashFunction(MS_UTILS_GETCOUNTRYLIST));
+ DestroyServiceFunction((HANDLE)NameHashFunction(MS_UTILS_GETCOUNTRYBYNUMBER));
+ hServiceGetList=CreateServiceFunction(MS_UTILS_GETCOUNTRYLIST,ServiceGetCountryList);
+ hServiceGetByNumber=CreateServiceFunction(MS_UTILS_GETCOUNTRYBYNUMBER,ServiceGetCountryByNumber);
+}
+
+void UninitCountryListExt(void)
+{
+ DestroyServiceFunction(hServiceGetList);
+ DestroyServiceFunction(hServiceGetByNumber);
+}
diff --git a/plugins/CountryFlags/docs/Flags-Developer.txt b/plugins/CountryFlags/docs/Flags-Developer.txt
new file mode 100644
index 0000000000..68c51a6d7c
--- /dev/null
+++ b/plugins/CountryFlags/docs/Flags-Developer.txt
@@ -0,0 +1,48 @@
+
+Country Flags 0.1.0.3 for Miranda IM 0.7+
+------------------------------------------------------------------------
+ Developer Information
+
+ Contents: -------------------------------
+ | Translation, Services (API),
+ | Debug Symbols, Coding Language, Rebase Info
+
+Translation
+-----------------
+ The translation string listing can be found in
+ 'Flags-Translation.txt'.
+
+Services (API)
+-----------------
+ For more information about which service functions are offered by
+ 'Country Flags' and about how they can be used by your plugin,
+ please refer to 'm_flags.h'.
+ If you would like to use Delphi/Pascal please refer to 'm_flags.inc'.
+
+ Please redirect any questions or extension whishes to me by e-mail:
+ hrathh at users.sourceforge.net
+
+Debug Symbols
+-----------------
+ Debug symbols are also available for debugging purposes.
+ Copy the PDB-files in the SDK-zip into the same directory as the
+ corresponding DLL-files.
+ To debug crashes the supplied MAP-file file might be helpful.
+
+Coding Language
+-----------------
+ 'Country Flags' was written using Microsoft Visual C++ 6.0 SP6
+ and the Microsoft Platform SDK shipped along with it.
+
+Rebase Info
+-----------------
+ 'Country Flags' has set its base address to:
+ 0x24200000
+
+ Please avoid using this base address for your plugins because it will
+ slow down the startup of Miranda IM.
+
+ Using Microsoft Visual C++, the base address can be configured at:
+ 'Project' -> 'Settings' -> 'Linker' -> 'Output' -> 'Base Address'
+
+H. Herkenrath (hrathh at users.sourceforge.net)
diff --git a/plugins/CountryFlags/docs/Flags-License.txt b/plugins/CountryFlags/docs/Flags-License.txt
new file mode 100644
index 0000000000..a726a52df1
--- /dev/null
+++ b/plugins/CountryFlags/docs/Flags-License.txt
@@ -0,0 +1,278 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
diff --git a/plugins/CountryFlags/docs/Flags-Readme.txt b/plugins/CountryFlags/docs/Flags-Readme.txt
new file mode 100644
index 0000000000..d6a2182fc6
--- /dev/null
+++ b/plugins/CountryFlags/docs/Flags-Readme.txt
@@ -0,0 +1,140 @@
+
+Country Flags 0.1.0.3
+------------------------------------------------------------------------
+ Plugin for Miranda IM 0.7 and +
+
+ Plugin Info: ----------------------------
+ | Version: 0.1.0.3
+ | Filename: flags.dll
+ | Author: H. Herkenrath (hrathh at users.sourceforge.net)
+ | Description: Service offering misc country utilities as
+ | flag icons and a IP-to-Country database.
+
+ Contents: -------------------------------
+ | Features, Requirements, Usage, Installation,
+ | Bugs and Wishes, Version History, License and Copyright
+
+Features
+----------------------
+ + Provides country utility services for other plugins (Flag Icons, IP-To-Country)
+ + Shows country flags as extra images on contact list
+ + Shows country flags as status icons on message windows
+ + Flag icon can be hidden if no country can be determined
+ + Flag icon is automatically refreshed when user details are updated
+ + Unicode compatible
+ + Automatic installation of all files, just unzip into Plugins directory
+
+Requirements
+----------------------
+ -> Miranda IM 0.7+:
+ Miranda IM is needed in version 0.7 or greater.
+
+Usage
+----------------------
+ Country Flags Provider does not add much functionality by itself.
+ It offers services for other plugins to use.
+
+ To show country flags on your contact list or
+ on your message window open the options and go here:
+ 'Contact List' -> 'Country Flags'
+
+ The country flag icons can be viewed here:
+ 'Customize' -> 'Icons'
+
+Installation
+----------------------
+ Find 'miranda32.exe' on your computer.
+
+ Just copy all the contents of the zip-file as they are into the 'Plugins' directory
+ in the Miranda IM folder.
+ 'Country Flags' will detect the files and move them into the appropriate
+ directories on it's first run.
+
+ You can also do all the installation by hand, if you want to:
+
+ Main Plugin: Copy the file 'flags.dll' into the 'Plugins' directory
+ in the Miranda IM folder.
+
+ The Unicode version of the plugin will only work on Windows NT/2000/XP,
+ Windows Server 2003, Windows Vista or later with an installed
+ Unicode version of Miranda IM.
+ To use it on Windows 95/98/Me, please download the ANSI version of the plugin.
+
+ Documentation: The txt-files should be moved along with the SDK-zip into the
+ 'Docs' directory in the Miranda IM folder.
+
+ That's it!
+
+Bugs and Wishes
+----------------------
+ Feel free to mail me your wishes about 'Language Pack Manager' and tell
+ me all the bugs you may find.
+ My email address is: hrathh at users.sourceforge.net
+
+Version History
+----------------------
+ 0.1.0.3 - really fixed those nasty crashes
+ - lightning-like speed due to buffered IP-database access
+ - option to turn-off usage of ip-to-country database
+ 0.1.0.2 - another try to fix those crashes
+ - refreshs icons on user details update
+ - optionally shows nothing if no country can be determined for a contact
+ 0.1.0.1 - try to fix those extraimg crashes
+ - fixed: implemented extra image column selector properly
+ - fixed: heavy crash on Unicode startup
+ (search on garbage might cross page-boundary)
+ - rewritten flags as status icons
+ - reimplemented country lookup
+ - added map-file to SDK package
+ 0.1.0.0 - Initial release
+
+License and Copyright
+----------------------
+ 'Country Flags' is released under the terms of the
+ GNU General Public License.
+ See 'Flags-License.txt' for more details.
+
+ Copyright (c) 2006-2007 by H. Herkenrath. All rights reserved.
+
+ This service includes the IP-to-Country Database
+ provided by WebHosting.info (http://www.webhosting.info),
+ available from http://ip-to-country.webhosting.info.
+ Copyright (c) 2003 Direct Information Pvt. Ltd. All rights Reserved.
+ Included Version: 05-03-2007, will be updated regularly.
+
+ The included Huffman encodig algorithm is
+ Copyright (c) 2003-2006 Marcus Geelnard.
+
+ The included default flag icons are public domain.
+ Flag Icons - http://www.famfamfam.com (created by Mark James)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. The origin of this software must not be misrepresented; you must
+ not claim that you wrote the original software. If you use this
+ software in a product, an acknowledgment in the product
+ documentation would be appreciated but is not required.
+ 3. Altered source versions must be plainly marked as such, and must
+ not be misrepresented as being the original software.
+ 4. The name of the author may not be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR 'AS IS' AND ANY EXPRESS
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+H. Herkenrath (hrathh at users.sourceforge.net)
diff --git a/plugins/CountryFlags/docs/Flags-Translation.txt b/plugins/CountryFlags/docs/Flags-Translation.txt
new file mode 100644
index 0000000000..15c1728c0d
--- /dev/null
+++ b/plugins/CountryFlags/docs/Flags-Translation.txt
@@ -0,0 +1,74 @@
+Country Flags 0.1.0.3 for Miranda IM 0.7+
+------------------------------------------------------------------------
+ Translator Information
+
+ Contents: -------------------------------
+ | General Info, String Listing
+
+General Info
+-----------------------------
+ 'Country Flags' can be translated using Miranda IM
+ language files.
+
+ Put the following strings in a file called 'langpack_<language>.txt'
+ in the Miranda IM directory and translate them into your
+ language.
+ If you need more info on Miranda IM language files visit:
+ http://miranda.svn.sourceforge.net/viewvc/*checkout*/miranda/trunk/miranda/i18n/readme.txt
+
+String Listing
+-----------------------------
+
+; --- Plugin: Country Flags 0.1.0.3 (German) ---
+; Translation by hrathh
+; Please report any mistakes or missing strings in here.
+
+[Country Flags]
+Länderflaggen
+[Service offering misc country utilities as flag icons and a IP-to-Country database.]
+Bietet verschiedene länderspezifische Dienste wie Flaggensymbole und IP-to-Country.
+[Country Flags Plugin]
+Länderflaggen-Plugin
+[The Country Flags Plugin can not be loaded. It requires Miranda IM %hs or later.]
+Der Länderflaggen-Plugin kann nicht geladen werden. Er benötigt Miranda IM %hs oder neuer.
+
+; Countries
+; Most country names are the same as used in miranda32.exe,
+; except the following corrections:
+[Australian Antarctic Territory]
+Australisches Antarktis-Territorium
+[Falkland Islands (Malvinas)]
+Falklandinseln (Malwinen)
+[Faroe Islands]
+Färöer-Inseln
+[Guantanamo Bay]
+Guantanamo-Bucht
+[Montenegro, Republic of]
+Montenegro
+[Saipan Island (Northern Mariana Islands)]
+Saipan Insel (Nördliche Marianen)
+;[Samoa]
+[Serbia, Republic of]
+Serbien
+
+; Options
+;[Contact List]
+;[Country Flags]
+[Show country flag as &status icon on message window]
+Zeige Länderflagge in der Statuszeile im Nachrichtenfenster
+[Show country flag as &extra image on contact list]
+Zeige Länderflagge als Spalte in der &Kontaktliste
+[In following contact list &column:]
+Verwende folgende &Spalte:
+[Advanced #%u]
+Erweitert #%u
+[Use &IP-to-country database for country detection]
+IP-Datenbank zur Bestimmung des Landes verwenden
+[Use &unknown flag if the country can not be determined]
+"Unbekannt" anzeigen, wenn Land nicht bestimmbar
+
+
+; ---
+
+
+H. Herkenrath (hrathh at users.sourceforge.net)
diff --git a/plugins/CountryFlags/extraimg.c b/plugins/CountryFlags/extraimg.c
new file mode 100644
index 0000000000..cd50cc2ccb
--- /dev/null
+++ b/plugins/CountryFlags/extraimg.c
@@ -0,0 +1,495 @@
+/*
+Miranda IM Country Flags Plugin
+Copyright (C) 2006-1007 H. Herkenrath
+
+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 (Flags-License.txt); if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "flags.h"
+
+/* Services */
+static HANDLE hServiceDetectContactOrigin;
+/* Extra Image */
+static HANDLE hHookExtraRebuild,hHookExtraApply;
+/* Status Icon */
+static HANDLE hHookMsgWndEvent,hHookIconsChanged;
+/* Options */
+static HANDLE hHookOptInit,hHookSettingChanged;
+/* Misc */
+extern HINSTANCE hInst;
+extern int nCountriesCount;
+extern struct CountryListEntry *countries;
+static HANDLE hHookModulesLoaded;
+
+/************************* Services *******************************/
+
+static int ServiceDetectContactOriginCountry(WPARAM wParam,LPARAM lParam)
+{
+ int countryNumber=0xFFFF;
+ char *pszProto;
+ UNREFERENCED_PARAMETER(lParam);
+ pszProto=(char*)CallService(MS_PROTO_GETCONTACTBASEPROTO,wParam,0);
+ /* ip detect */
+ if(DBGetContactSettingByte(NULL,"Flags","UseIpToCountry",SETTING_USEIPTOCOUNTRY_DEFAULT))
+ countryNumber=ServiceIpToCountry(DBGetContactSettingDword((HANDLE)wParam,pszProto,"RealIP",0),0);
+ /* fallback */
+ if(countryNumber==0xFFFF)
+ countryNumber=DBGetContactSettingWord((HANDLE)wParam,pszProto,"Country",0);
+ if(countryNumber==0 || countryNumber==0xFFFF)
+ countryNumber=DBGetContactSettingWord((HANDLE)wParam,pszProto,"CompanyCountry",0);
+ return (countryNumber==0)?0xFFFF:countryNumber;
+}
+
+/************************* Extra Image ****************************/
+
+#define EXTRAIMAGE_REFRESHDELAY 100 /* time for which setting changes are buffered */
+
+static HANDLE *phExtraImages;
+static BYTE idExtraColumn;
+
+static void CALLBACK SetExtraImage(LPARAM lParam)
+{
+ IconExtraColumn iec;
+ int countryNumber,index;
+ if(DBGetContactSettingByte(NULL,"Flags","ShowExtraImgFlag",SETTING_SHOWEXTRAIMGFLAG_DEFAULT)) {
+ /* get contact's country */
+ iec.hImage=INVALID_HANDLE_VALUE;
+ countryNumber=ServiceDetectContactOriginCountry((WPARAM)lParam,0);
+ /* get icon */
+ if(phExtraImages!=NULL) /* too early? */
+ if(countryNumber!=0xFFFF || DBGetContactSettingByte(NULL,"Flags","UseUnknownFlag",SETTING_USEUNKNOWNFLAG_DEFAULT)) {
+ index=CountryNumberToIndex(countryNumber);
+ /* icon not yet loaded? */
+ if(phExtraImages[index]==INVALID_HANDLE_VALUE) {
+ HICON hIcon;
+ hIcon=LoadFlagIcon(countryNumber);
+ if(hIcon!=NULL) phExtraImages[index]=(HANDLE)CallService(MS_CLIST_EXTRA_ADD_ICON,(WPARAM)hIcon,0);
+ CallService(MS_SKIN2_RELEASEICON,(WPARAM)hIcon,0); /* does NULL check */
+ }
+ iec.hImage=phExtraImages[index];
+ }
+ /* choose column */
+ iec.cbSize=sizeof(iec);
+ iec.ColumnType=idExtraColumn;
+ CallService(MS_CLIST_EXTRA_SET_ICON,(WPARAM)lParam,(LPARAM)&iec);
+ }
+}
+
+// always call in context of main thread
+static void RemoveExtraImages(void)
+{
+ IconExtraColumn iec;
+ register HANDLE hContact;
+ /* choose column */
+ iec.cbSize=sizeof(iec);
+ iec.ColumnType=idExtraColumn;
+ iec.hImage=INVALID_HANDLE_VALUE;
+ /* enum all contacts */
+ hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+ while(hContact!=NULL) {
+ /* invalidate icon */
+ CallService(MS_CLIST_EXTRA_SET_ICON,(WPARAM)hContact,(LPARAM)&iec);
+ hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0);
+ }
+}
+
+// always call in context of main thread
+static void EnsureExtraImages(void)
+{
+ register HANDLE hContact;
+ BYTE idMaxExtraCol,idExtraColumnNew;
+ /* choose column */
+ idMaxExtraCol=(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_EXTRACOLUMNCOUNT); /* 1-based count */
+ if(idMaxExtraCol==(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_USEREXTRASTART)) /* same flags if not present */
+ idMaxExtraCol=EXTRA_ICON_ADV2; /* zero if not present */
+ idExtraColumnNew=DBGetContactSettingRangedByte(NULL,"Flags","ExtraImgFlagColumn",SETTING_EXTRAIMGFLAGCOLUMN_DEFAULT,1,idMaxExtraCol);
+ /* clear previous column */
+ if(idExtraColumnNew!=idExtraColumn) RemoveExtraImages();
+ idExtraColumn=idExtraColumnNew;
+ /* enum all contacts */
+ hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+ while(hContact!=NULL) {
+ CallFunctionBuffered(SetExtraImage,(LPARAM)hContact,TRUE,EXTRAIMAGE_REFRESHDELAY);
+ hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)hContact,0);
+ }
+}
+
+static void CALLBACK UpdateExtraImages(LPARAM lParam)
+{
+ UNREFERENCED_PARAMETER(lParam);
+ if(DBGetContactSettingByte(NULL,"Flags","ShowExtraImgFlag",SETTING_SHOWEXTRAIMGFLAG_DEFAULT))
+ EnsureExtraImages();
+ else RemoveExtraImages();
+}
+
+static int ExtraListRebuild(WPARAM wParam,LPARAM lParam)
+{
+ BYTE idMaxExtraCol;
+ int i;
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+ OutputDebugStringA("REBUILD EXTRA\n");
+ /* invalidate icons */
+ if(phExtraImages!=NULL)
+ for(i=0;i<nCountriesCount;++i)
+ phExtraImages[i]=INVALID_HANDLE_VALUE;
+ /* choose column */
+ idMaxExtraCol=(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_EXTRACOLUMNCOUNT); /* 1-based count */
+ if(idMaxExtraCol==(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_USEREXTRASTART)) /* same flags if not present */
+ idMaxExtraCol=EXTRA_ICON_ADV2; /* zero if not present */
+ idExtraColumn=DBGetContactSettingRangedByte(NULL,"Flags","ExtraImgFlagColumn",SETTING_EXTRAIMGFLAGCOLUMN_DEFAULT,1,idMaxExtraCol);
+ return 0;
+}
+
+static int ExtraImageApply(WPARAM wParam,LPARAM lParam)
+{
+ UNREFERENCED_PARAMETER(lParam);
+ OutputDebugStringA("APPLY EXTRA\n");
+ if(DBGetContactSettingByte(NULL,"Flags","ShowExtraImgFlag",SETTING_SHOWEXTRAIMGFLAG_DEFAULT))
+ SetExtraImage((LPARAM)wParam); /* unbuffered */
+ return 0;
+}
+
+/************************* Status Icon ****************************/
+
+#define STATUSICON_REFRESHDELAY 100 /* time for which setting changes are buffered */
+
+// always call in context of main thread
+static void FASTCALL SetStatusIcon(HANDLE hContact,int countryNumber)
+{
+ int i;
+ HICON hIcon=NULL;
+ StatusIconData sid;
+
+ if(countryNumber!=0xFFFF || DBGetContactSettingByte(NULL,"Flags","UseUnknownFlag",SETTING_USEUNKNOWNFLAG_DEFAULT)) {
+ /* copy icon as status icon API will call DestroyIcon() on it */
+ hIcon=LoadFlagIcon(countryNumber);
+ sid.hIcon=(hIcon!=NULL)?CopyIcon(hIcon):NULL;
+ CallService(MS_SKIN2_RELEASEICON,(WPARAM)hIcon,0); /* does NULL check */
+ hIcon=sid.hIcon;
+ /* ensure status icon is registered */
+ sid.cbSize=sizeof(sid);
+ sid.szModule="Flags";
+ sid.dwId=countryNumber;
+ sid.hIconDisabled=NULL;
+ sid.flags=0;
+ sid.szTooltip=Translate((char*)CallService(MS_UTILS_GETCOUNTRYBYNUMBER,countryNumber,0));
+ if(CallService(MS_MSG_MODIFYICON,0,(LPARAM)&sid)) /* not yet registered? */
+ CallService(MS_MSG_ADDICON,0,(LPARAM)&sid);
+ }
+ /* disable all other flags for this contact */
+ sid.hIcon=NULL;
+ sid.szTooltip=NULL;
+ sid.flags=MBF_HIDDEN;
+ for(i=0;i<nCountriesCount;++i) {
+ sid.dwId=countries[i].id;
+ if(countryNumber==countries[i].id && hIcon!=NULL) sid.flags=0;
+ else sid.flags=MBF_HIDDEN;
+ CallService(MS_MSG_MODIFYICON,(WPARAM)hContact,(LPARAM)&sid);
+ }
+}
+
+// always call in context of main thread
+static void FASTCALL UnsetStatusIcon(HANDLE hContact,int countryNumber)
+{
+ StatusIconData sid;
+ sid.cbSize=sizeof(sid);
+ sid.szModule="Flags";
+ sid.dwId=countryNumber;
+ sid.hIconDisabled=sid.hIcon=NULL;
+ sid.szTooltip=NULL;
+ sid.flags=MBF_HIDDEN;
+ CallService(MS_MSG_MODIFYICON,(WPARAM)hContact,(LPARAM)&sid); /* registered? */
+ /* can't call MS_MSG_REMOVEICON here as the icon might be
+ * in use by other contacts simultanously, removing them all at exit */
+}
+
+static int MsgWndEvent(WPARAM wParam,LPARAM lParam)
+{
+ MessageWindowEventData *msgwe=(MessageWindowEventData*)lParam;
+ UNREFERENCED_PARAMETER(wParam);
+ switch(msgwe->uType) {
+ case MSG_WINDOW_EVT_OPENING:
+ case MSG_WINDOW_EVT_CLOSE:
+ { int countryNumber;
+ if(msgwe->hContact==NULL || !ServiceExists(MS_MSG_ADDICON)) break; /* sanity check */
+ countryNumber=ServiceDetectContactOriginCountry((WPARAM)msgwe->hContact,0);
+ if(DBGetContactSettingByte(NULL,"Flags","ShowStatusIconFlag",SETTING_SHOWSTATUSICONFLAG_DEFAULT)) {
+ if(msgwe->uType==MSG_WINDOW_EVT_OPENING) SetStatusIcon(msgwe->hContact,countryNumber);
+ else UnsetStatusIcon(msgwe->hContact,countryNumber);
+ }
+ /* ensure it is hidden, RemoveStatusIcons() only enums currently opened ones */
+ else UnsetStatusIcon(msgwe->hContact,countryNumber);
+ }
+ }
+ return 0;
+}
+
+static void CALLBACK UpdateStatusIcons(LPARAM lParam)
+{
+ MessageWindowInputData msgwi; /* input */
+ MessageWindowData msgw; /* output */
+ BOOL fShow;
+ int countryNumber;
+ UNREFERENCED_PARAMETER(lParam);
+
+ msgwi.cbSize=sizeof(msgwi);
+ msgw.cbSize=sizeof(msgw);
+ msgwi.uFlags=MSG_WINDOW_UFLAG_MSG_BOTH;
+ /* enum all opened message windows */
+ fShow=DBGetContactSettingByte(NULL,"Flags","ShowStatusIconFlag",SETTING_SHOWSTATUSICONFLAG_DEFAULT);
+ msgwi.hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDFIRST,0,0);
+ while(msgwi.hContact!=NULL) {
+ /* is a message window opened for this contact? */
+ if(!CallService(MS_MSG_GETWINDOWDATA,(WPARAM)&msgwi,(LPARAM)&msgw) && msgw.uState&MSG_WINDOW_STATE_EXISTS) {
+ countryNumber=ServiceDetectContactOriginCountry((WPARAM)msgwi.hContact,0);
+ if(fShow) SetStatusIcon(msgwi.hContact,countryNumber);
+ else UnsetStatusIcon(msgwi.hContact,countryNumber);
+ }
+ msgwi.hContact=(HANDLE)CallService(MS_DB_CONTACT_FINDNEXT,(WPARAM)msgw.hContact,0);
+ }
+}
+
+static int StatusIconsChanged(WPARAM wParam,LPARAM lParam)
+{
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+ if(ServiceExists(MS_MSG_ADDICON))
+ if(DBGetContactSettingByte(NULL,"Flags","ShowStatusIconFlag",SETTING_SHOWSTATUSICONFLAG_DEFAULT))
+ CallFunctionBuffered(UpdateStatusIcons,0,FALSE,STATUSICON_REFRESHDELAY);
+ return 0;
+}
+
+/************************* Options ************************************/
+
+#define M_ENABLE_SUBCTLS (WM_APP+1)
+
+static int CALLBACK ExtraImgOptDlgProc(HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)
+{
+ UNREFERENCED_PARAMETER(wParam);
+ switch(msg) {
+ case WM_INITDIALOG:
+ TranslateDialogDefault(hwndDlg);
+ /* init checkboxes */
+ { BOOL val;
+ /* Status Icon */
+ if(ServiceExists(MS_MSG_ADDICON)) val=DBGetContactSettingByte(NULL,"Flags","ShowStatusIconFlag",SETTING_SHOWSTATUSICONFLAG_DEFAULT)!=0;
+ else EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_SHOWSTATUSICONFLAG),val=FALSE);
+ CheckDlgButton(hwndDlg,IDC_CHECK_SHOWSTATUSICONFLAG,val);
+ /* Extra Image */
+ if(ServiceExists(MS_CLIST_EXTRA_ADD_ICON)) val=DBGetContactSettingByte(NULL,"Flags","ShowExtraImgFlag",SETTING_SHOWEXTRAIMGFLAG_DEFAULT)!=0;
+ else EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_SHOWEXTRAIMGFLAG),val=FALSE);
+ CheckDlgButton(hwndDlg,IDC_CHECK_SHOWEXTRAIMGFLAG,val);
+ /* Unknown Flag */
+ val=DBGetContactSettingByte(NULL,"Flags","UseUnknownFlag",SETTING_USEUNKNOWNFLAG_DEFAULT)!=0;
+ CheckDlgButton(hwndDlg,IDC_CHECK_USEUNKNOWNFLAG,val);
+ /* IP-to-country */
+ val=DBGetContactSettingByte(NULL,"Flags","UseIpToCountry",SETTING_USEIPTOCOUNTRY_DEFAULT)!=0;
+ CheckDlgButton(hwndDlg,IDC_CHECK_USEIPTOCOUNTRY,val);
+ }
+ /* init combobox */
+ { HWND hwndCombo;
+ TCHAR szItem[64];
+ BYTE idColumn,idSavedColumn;
+ BYTE idMaxExtraCol,idAdvExtraColStart;
+ int index;
+ hwndCombo=GetDlgItem(hwndDlg,IDC_COMBO_EXTRAIMGFLAGCOLUMN);
+ idSavedColumn=DBGetContactSettingByte(NULL,"Flags","ExtraImgFlagColumn",SETTING_EXTRAIMGFLAGCOLUMN_DEFAULT);
+ idMaxExtraCol=(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_EXTRACOLUMNCOUNT); /* 1-based count */
+ idAdvExtraColStart=(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_USEREXTRASTART); /* 1-based id */
+ /* init */
+ SendMessage(hwndCombo,CB_SETLOCALE,(LCID)CallService(MS_LANGPACK_GETLOCALE,0,0),0); /* for sort order */
+ SendMessage(hwndCombo,CB_INITSTORAGE,idMaxExtraCol-idAdvExtraColStart+3,(idMaxExtraCol-idAdvExtraColStart+3)*SIZEOF(szItem));
+ /* Advanced #1,#2 */
+ { const BYTE columnIds[]={EXTRA_ICON_ADV1,EXTRA_ICON_ADV2};
+ for(idColumn=0;idColumn<SIZEOF(columnIds);++idColumn) {
+ mir_sntprintf(szItem,SIZEOF(szItem),TranslateT("Advanced #%u"),idColumn+1); /* buffer safe */
+ index=SendMessage(hwndCombo,CB_ADDSTRING,0,(LPARAM)szItem);
+ if(index!=LB_ERR) {
+ SendMessage(hwndCombo,CB_SETITEMDATA,index,columnIds[idColumn]);
+ if(idColumn==0 || columnIds[idColumn]==idSavedColumn) SendMessage(hwndCombo,CB_SETCURSEL,index,0);
+ }
+ }
+ }
+ /* Advanced #3+: clist_modern */
+ if(idMaxExtraCol!=idAdvExtraColStart) /* same flags if not present */
+ for(idColumn=idAdvExtraColStart;idColumn<=idMaxExtraCol;++idColumn) {
+ mir_sntprintf(szItem,SIZEOF(szItem),TranslateT("Advanced #%u"),idColumn-idAdvExtraColStart+3); /* buffer safe */
+ index=SendMessage(hwndCombo,CB_ADDSTRING,0,(LPARAM)szItem);
+ if(index!=LB_ERR) {
+ SendMessage(hwndCombo,CB_SETITEMDATA,index,idColumn);
+ if(idColumn==idSavedColumn) SendMessage(hwndCombo,CB_SETCURSEL,index,0);
+ }
+ }
+ }
+ SendMessage(hwndDlg,M_ENABLE_SUBCTLS,0,0);
+ return TRUE; /* default focus */
+ case M_ENABLE_SUBCTLS:
+ { BOOL checked=IsDlgButtonChecked(hwndDlg,IDC_CHECK_SHOWEXTRAIMGFLAG);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_TEXT_EXTRAIMGFLAGCOLUMN),checked);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_COMBO_EXTRAIMGFLAGCOLUMN),checked);
+ if(!checked) checked=IsDlgButtonChecked(hwndDlg,IDC_CHECK_SHOWSTATUSICONFLAG);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_USEUNKNOWNFLAG),checked);
+ EnableWindow(GetDlgItem(hwndDlg,IDC_CHECK_USEIPTOCOUNTRY),checked);
+ return TRUE;
+ }
+ case WM_COMMAND:
+ PostMessage(hwndDlg,M_ENABLE_SUBCTLS,0,0);
+ PostMessage(GetParent(hwndDlg),PSM_CHANGED,0,0); /* enable apply */
+ return FALSE;
+ case WM_NOTIFY:
+ switch(((NMHDR*)lParam)->code) {
+ case PSN_APPLY: /* setting change hook will pick these up */
+ DBWriteContactSettingByte(NULL,"Flags","UseUnknownFlag",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_USEUNKNOWNFLAG)!=0));
+ DBWriteContactSettingByte(NULL,"Flags","UseIpToCountry",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_USEIPTOCOUNTRY)!=0));
+ /* Status Icon */
+ if(IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHECK_SHOWSTATUSICONFLAG)))
+ DBWriteContactSettingByte(NULL,"Flags","ShowStatusIconFlag",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_SHOWSTATUSICONFLAG)!=0));
+ /* Extra Image */
+ if(IsWindowEnabled(GetDlgItem(hwndDlg,IDC_CHECK_SHOWEXTRAIMGFLAG)))
+ DBWriteContactSettingByte(NULL,"Flags","ShowExtraImgFlag",(BYTE)(IsDlgButtonChecked(hwndDlg,IDC_CHECK_SHOWEXTRAIMGFLAG)!=0));
+ { int index;
+ index=SendDlgItemMessage(hwndDlg,IDC_COMBO_EXTRAIMGFLAGCOLUMN,CB_GETCURSEL,0,0);
+ if(index!=LB_ERR) DBWriteContactSettingByte(NULL,"Flags","ExtraImgFlagColumn",(BYTE)SendDlgItemMessage(hwndDlg,IDC_COMBO_EXTRAIMGFLAGCOLUMN,CB_GETITEMDATA,index,0));
+ }
+ return TRUE;
+ }
+ break;
+ }
+ return FALSE;
+}
+
+static int ExtraImgOptInit(WPARAM wParam,LPARAM lParam)
+{
+ OPTIONSDIALOGPAGE odp;
+ static UINT expertOnlyControls[]={IDC_CHECK_USEIPTOCOUNTRY};
+ UNREFERENCED_PARAMETER(lParam);
+ ZeroMemory(&odp,sizeof(odp));
+ odp.cbSize=sizeof(odp);
+ odp.hInstance=hInst;
+ odp.pszTemplate=MAKEINTRESOURCEA(IDD_OPT_EXTRAIMG);
+ odp.position=900000002;
+ odp.ptszGroup=_T("Contact List"); /* autotranslated */
+ odp.ptszTitle=_T("Country Flags"); /* autotranslated */
+ odp.ptszTab=_T("Country Flags"); /* autotranslated, can be made a tab */
+ odp.flags=ODPF_BOLDGROUPS|ODPF_TCHAR;
+ odp.pfnDlgProc=ExtraImgOptDlgProc;
+ odp.expertOnlyControls=expertOnlyControls;
+ odp.nExpertOnlyControls=SIZEOF(expertOnlyControls);
+ CallService(MS_OPT_ADDPAGE,wParam,(LPARAM)&odp);
+ return 0;
+}
+
+static int ExtraImgSettingChanged(WPARAM wParam,LPARAM lParam)
+{
+ DBCONTACTWRITESETTING *dbcws=(DBCONTACTWRITESETTING*)lParam;
+ if((HANDLE)wParam==NULL) {
+ if(!lstrcmpA(dbcws->szModule,"Flags")) {
+ /* Extra Image */
+ if(!lstrcmpA(dbcws->szSetting,"ShowExtraImgFlag") ||
+ !lstrcmpA(dbcws->szSetting,"ExtraImgFlagColumn") ||
+ !lstrcmpA(dbcws->szSetting,"UseUnknownFlag") ||
+ !lstrcmpA(dbcws->szSetting,"UseIpToCountry"))
+ if(ServiceExists(MS_CLIST_EXTRA_SET_ICON))
+ CallFunctionBuffered(UpdateExtraImages,0,FALSE,EXTRAIMAGE_REFRESHDELAY);
+ /* Status Icon */
+ if(!lstrcmpA(dbcws->szSetting,"ShowStatusIconFlag") ||
+ !lstrcmpA(dbcws->szSetting,"UseUnknownFlag") ||
+ !lstrcmpA(dbcws->szSetting,"UseIpToCountry"))
+ if(ServiceExists(MS_MSG_ADDICON))
+ CallFunctionBuffered(UpdateStatusIcons,0,FALSE,STATUSICON_REFRESHDELAY);
+ }
+ }
+ /* user details update */
+ else if(!lstrcmpA(dbcws->szSetting,"RealIP") ||
+ !lstrcmpA(dbcws->szSetting,"Country") ||
+ !lstrcmpA(dbcws->szSetting,"CompanyCountry")) {
+ /* Extra Image */
+ if(ServiceExists(MS_CLIST_EXTRA_SET_ICON))
+ CallFunctionBuffered(SetExtraImage,(LPARAM)wParam,TRUE,EXTRAIMAGE_REFRESHDELAY);
+ /* Status Icon */
+ if(ServiceExists(MS_MSG_ADDICON))
+ CallFunctionBuffered(UpdateStatusIcons,0,FALSE,STATUSICON_REFRESHDELAY);
+ }
+ return 0;
+}
+
+/************************* Misc ***********************************/
+
+static int ExtraImgModulesLoaded(WPARAM wParam,LPARAM lParam)
+{
+ UNREFERENCED_PARAMETER(wParam);
+ UNREFERENCED_PARAMETER(lParam);
+ /* Options */
+ if(ServiceExists("DBEditorpp/RegisterSingleModule"))
+ CallService("DBEditorpp/RegisterSingleModule",(WPARAM)"Flags",0);
+ /* Extra Image */
+ if(ServiceExists(MS_CLIST_EXTRA_SET_ICON)) {
+ int i;
+ BYTE idMaxExtraCol;
+ phExtraImages=(HANDLE*)mir_alloc(nCountriesCount*sizeof(HANDLE));
+ /* invalidate icons */
+ if(phExtraImages!=NULL)
+ for(i=0;i<nCountriesCount;++i)
+ phExtraImages[i]=INVALID_HANDLE_VALUE;
+ /* choose column */
+ idMaxExtraCol=(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_EXTRACOLUMNCOUNT); /* 1-based count */
+ if(idMaxExtraCol==(BYTE)CallService(MS_CLUI_GETCAPS,0,CLUIF2_USEREXTRASTART)) /* same flags if not present */
+ idMaxExtraCol=EXTRA_ICON_ADV2; /* zero if not present */
+ idExtraColumn=DBGetContactSettingRangedByte(NULL,"Flags","ExtraImgFlagColumn",SETTING_EXTRAIMGFLAGCOLUMN_DEFAULT,1,idMaxExtraCol);
+ /* hook */
+ hHookExtraRebuild=HookEvent(ME_CLIST_EXTRA_LIST_REBUILD,ExtraListRebuild);
+ hHookExtraApply=HookEvent(ME_CLIST_EXTRA_IMAGE_APPLY,ExtraImageApply);
+ }
+ /* Status Icon */
+ hHookMsgWndEvent=HookEvent(ME_MSG_WINDOWEVENT,MsgWndEvent);
+ return 0;
+}
+
+void InitExtraImg(void)
+{
+ /* Services */
+ hServiceDetectContactOrigin=CreateServiceFunction(MS_FLAGS_DETECTCONTACTORIGINCOUNTRY,ServiceDetectContactOriginCountry);
+ /* Misc */
+ hHookModulesLoaded=HookEvent(ME_SYSTEM_MODULESLOADED,ExtraImgModulesLoaded);
+ /* Extra Image */
+ phExtraImages=NULL;
+ hHookExtraRebuild=hHookExtraApply=NULL;
+ /* Status icon */
+ hHookMsgWndEvent=NULL;
+ hHookIconsChanged=HookEvent(ME_SKIN2_ICONSCHANGED,StatusIconsChanged);
+ /* Options */
+ hHookOptInit=HookEvent(ME_OPT_INITIALISE,ExtraImgOptInit);
+ hHookSettingChanged=HookEvent(ME_DB_CONTACT_SETTINGCHANGED,ExtraImgSettingChanged);
+}
+
+void UninitExtraImg(void)
+{
+ /* Services */
+ DestroyServiceFunction(hServiceDetectContactOrigin);
+ /* Misc */
+ UnhookEvent(hHookModulesLoaded);
+ /* Extra Image */
+ UnhookEvent(hHookSettingChanged);
+ UnhookEvent(hHookExtraRebuild);
+ UnhookEvent(hHookExtraApply);
+ mir_free(phExtraImages); /* does NULL check */
+ /* Status icon */
+ UnhookEvent(hHookMsgWndEvent);
+ UnhookEvent(hHookIconsChanged);
+ /* Options */
+ UnhookEvent(hHookOptInit);
+ UnhookEvent(hHookSettingChanged);
+}
diff --git a/plugins/CountryFlags/flags.def b/plugins/CountryFlags/flags.def
new file mode 100644
index 0000000000..fb2cd5c0ef
--- /dev/null
+++ b/plugins/CountryFlags/flags.def
@@ -0,0 +1,11 @@
+LIBRARY flags BASE=0x24200000
+SECTIONS
+ ; obfuscated email address
+ .rdata READ WRITE
+EXPORTS
+ MirandaPluginInfo PRIVATE
+ Load PRIVATE
+ Unload PRIVATE
+ ; v0.8 support
+ MirandaPluginInfoEx PRIVATE
+ MirandaPluginInterfaces PRIVATE
diff --git a/plugins/CountryFlags/flags.h b/plugins/CountryFlags/flags.h
new file mode 100644
index 0000000000..cd7837e3d4
--- /dev/null
+++ b/plugins/CountryFlags/flags.h
@@ -0,0 +1,89 @@
+/*
+Miranda IM Country Flags Plugin
+Copyright (C) 2006-2007 H. Herkenrath
+
+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 (Flags-License.txt); if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#define NONAMELESSUNION
+#include <commctrl.h> /* for ImageList functions */
+#define NOWIN2K
+#include <win2k.h>
+#define MIRANDA_VER 0x0700
+#include <stdio.h>
+#include <newpluginapi.h>
+#include <m_system.h>
+#include <m_utils.h>
+#include <m_langpack.h>
+#include <m_icolib.h>
+#include <m_clui.h>
+#include <m_cluiframes.h>
+#include <m_message.h>
+#include <m_database.h>
+#include <m_options.h>
+#include <m_contacts.h>
+#include <m_protocols.h>
+#define FLAGS_NOHELPERFUNCTIONS
+#include "m_flags.h"
+#include "resource.h"
+
+#if defined(_MSC_VER) && !defined(FASTCALL)
+ #define FASTCALL __fastcall
+#else
+ #define FASTCALL
+#endif
+#if defined(_DEBUG)
+ #undef FASTCALL
+ #define FASTCALL
+#endif
+
+/* countrylistext.c */
+void InitCountryListExt(void);
+void UninitCountryListExt(void);
+
+/* huffman.c */
+#ifdef HUFFMAN_ENCODE
+ int Huffman_Compress(unsigned char *in,unsigned char *out,unsigned int insize );
+#endif
+void Huffman_Uncompress(unsigned char *in,unsigned char *out,unsigned int insize,unsigned int outsize);
+
+/* icons.c */
+HICON FASTCALL LoadFlagIcon(int countryNumber);
+int FASTCALL CountryNumberToIndex(int countryNumber);
+void InitIcons(void);
+void UninitIcons(void);
+
+/* ip2country.c */
+int ServiceIpToCountry(WPARAM wParam,LPARAM lParam);
+void InitIpToCountry(void);
+void UninitIpToCountry(void);
+
+/* extraimg.c */
+void InitExtraImg(void);
+void UninitExtraImg(void);
+
+/* utils.c */
+typedef void (CALLBACK *BUFFEREDPROC)(LPARAM lParam);
+#ifdef _DEBUG
+ void _CallFunctionBuffered(BUFFEREDPROC pfnBuffProc,const char *pszProcName,LPARAM lParam,BOOL fAccumulateSameParam,UINT uElapse);
+ #define CallFunctionBuffered(proc,param,acc,elapse) _CallFunctionBuffered(proc,#proc,param,acc,elapse)
+#else
+ void _CallFunctionBuffered(BUFFEREDPROC pfnBuffProc,LPARAM lParam,BOOL fAccumulateSameParam,UINT uElapse);
+ #define CallFunctionBuffered(proc,param,acc,elapse) _CallFunctionBuffered(proc,param,acc,elapse)
+#endif
+void PrepareBufferedFunctions(void);
+void KillBufferedFunctions(void);
diff --git a/plugins/CountryFlags/flags.sln b/plugins/CountryFlags/flags.sln
new file mode 100644
index 0000000000..1903a8eb95
--- /dev/null
+++ b/plugins/CountryFlags/flags.sln
@@ -0,0 +1,29 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flags", "flags.vcxproj", "{0966244A-B8FD-FF88-DA2F-6A8332BCD82F}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Bin Converter|Win32 = Bin Converter|Win32
+ Debug Unicode|Win32 = Debug Unicode|Win32
+ Debug|Win32 = Debug|Win32
+ Release Unicode|Win32 = Release Unicode|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0966244A-B8FD-FF88-DA2F-6A8332BCD82F}.Bin Converter|Win32.ActiveCfg = Bin Converter|Win32
+ {0966244A-B8FD-FF88-DA2F-6A8332BCD82F}.Bin Converter|Win32.Build.0 = Bin Converter|Win32
+ {0966244A-B8FD-FF88-DA2F-6A8332BCD82F}.Debug Unicode|Win32.ActiveCfg = Debug Unicode|Win32
+ {0966244A-B8FD-FF88-DA2F-6A8332BCD82F}.Debug Unicode|Win32.Build.0 = Debug Unicode|Win32
+ {0966244A-B8FD-FF88-DA2F-6A8332BCD82F}.Debug|Win32.ActiveCfg = Debug|Win32
+ {0966244A-B8FD-FF88-DA2F-6A8332BCD82F}.Debug|Win32.Build.0 = Debug|Win32
+ {0966244A-B8FD-FF88-DA2F-6A8332BCD82F}.Release Unicode|Win32.ActiveCfg = Release Unicode|Win32
+ {0966244A-B8FD-FF88-DA2F-6A8332BCD82F}.Release Unicode|Win32.Build.0 = Release Unicode|Win32
+ {0966244A-B8FD-FF88-DA2F-6A8332BCD82F}.Release|Win32.ActiveCfg = Release|Win32
+ {0966244A-B8FD-FF88-DA2F-6A8332BCD82F}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/plugins/CountryFlags/flags.vcxproj b/plugins/CountryFlags/flags.vcxproj
new file mode 100644
index 0000000000..18ab33ade6
--- /dev/null
+++ b/plugins/CountryFlags/flags.vcxproj
@@ -0,0 +1,408 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Bin Converter|Win32">
+ <Configuration>Bin Converter</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug Unicode|Win32">
+ <Configuration>Debug Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release Unicode|Win32">
+ <Configuration>Release Unicode</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <SccProjectName />
+ <SccLocalPath />
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Bin Converter|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>MultiByte</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <UseOfMfc>false</UseOfMfc>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Bin Converter|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ <Import Project="$(VCTargetsPath)Microsoft.Cpp.UpgradeFromVC60.props" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ <IgnoreImportLibrary>true</IgnoreImportLibrary>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Bin Converter|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ <IgnoreImportLibrary>true</IgnoreImportLibrary>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <IgnoreImportLibrary>true</IgnoreImportLibrary>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental>false</LinkIncremental>
+ <IgnoreImportLibrary>true</IgnoreImportLibrary>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <OutDir>$(SolutionDir)$(Configuration)/Plugins\</OutDir>
+ <IntDir>$(SolutionDir)$(Configuration)/Obj/$(ProjectName)\</IntDir>
+ <LinkIncremental>true</LinkIncremental>
+ <IgnoreImportLibrary>true</IgnoreImportLibrary>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug Unicode|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;UNICODE;WIN32;_WINDOWS;_USRDLL;STRICT;FLAGS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <UndefinePreprocessorDefinitions>_MBCS;NO_STRICT;%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+ <BrowseInformation>true</BrowseInformation>
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\temp/Debug/Unicode\flags.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0809</Culture>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <IgnoreSpecificDefaultLibraries>uuid.lib;OLDNAMES;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>flags.def</ModuleDefinitionFile>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <BaseAddress>0x24200000</BaseAddress>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalOptions> /mapinfo:lines /mapinfo:lines </AdditionalOptions>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Bin Converter|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>BINCONV;HUFFMAN_ENCODE;_DEBUG;WIN32;_WINDOWS;_USRDLL;STRICT;FLAGS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <UndefinePreprocessorDefinitions>NO_STRICT;%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+ <BrowseInformation>true</BrowseInformation>
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\temp/BinConv\flags.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0809</Culture>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <IgnoreSpecificDefaultLibraries>uuid.lib;OLDNAMES;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>flags.def</ModuleDefinitionFile>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <BaseAddress>0x25000000</BaseAddress>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalOptions> /mapinfo:lines</AdditionalOptions>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>Full</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;WIN32;_WINDOWS;_USRDLL;STRICT;ASSOCMGR_EXPORTS;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <UndefinePreprocessorDefinitions>NO_STRICT;%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+ <BrowseInformation>true</BrowseInformation>
+ <AdditionalOptions> /opt:nowin98 </AdditionalOptions>
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\temp/Release/ANSI\flags.tlb</TypeLibraryName>
+ <MkTypLibCompatible>false</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0809</Culture>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <IgnoreSpecificDefaultLibraries>uuid.lib;OLDNAMES;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>flags.def</ModuleDefinitionFile>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <SetChecksum>true</SetChecksum>
+ <BaseAddress>0x24200000</BaseAddress>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalOptions>/ignore:4078 </AdditionalOptions>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <StringPooling>true</StringPooling>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <Optimization>Full</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;UNICODE;WIN32;_WINDOWS;_USRDLL;STRICT;ASSOCMGR_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <UndefinePreprocessorDefinitions>_MBCS;NO_STRICT;%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+ <BrowseInformation>true</BrowseInformation>
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+ <AdditionalOptions> /opt:nowin98 </AdditionalOptions>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\temp/Release/Unicode\flags.tlb</TypeLibraryName>
+ <MkTypLibCompatible>false</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0809</Culture>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>NDEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <IgnoreSpecificDefaultLibraries>uuid.lib;OLDNAMES;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>flags.def</ModuleDefinitionFile>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <SetChecksum>true</SetChecksum>
+ <BaseAddress>0x24200000</BaseAddress>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalOptions>/ignore:4078 </AdditionalOptions>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+ <InlineFunctionExpansion>Default</InlineFunctionExpansion>
+ <FunctionLevelLinking>false</FunctionLevelLinking>
+ <Optimization>Disabled</Optimization>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <WarningLevel>Level4</WarningLevel>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;_USRDLL;STRICT;FLAGS_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <UndefinePreprocessorDefinitions>NO_STRICT;%(UndefinePreprocessorDefinitions)</UndefinePreprocessorDefinitions>
+ <BrowseInformation>true</BrowseInformation>
+ <PrecompiledHeaderOutputFile>$(IntDir)$(TargetName).pch</PrecompiledHeaderOutputFile>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ </ClCompile>
+ <Midl>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <TypeLibraryName>.\temp/Debug/ANSI\flags.tlb</TypeLibraryName>
+ <MkTypLibCompatible>true</MkTypLibCompatible>
+ <TargetEnvironment>Win32</TargetEnvironment>
+ </Midl>
+ <ResourceCompile>
+ <Culture>0x0809</Culture>
+ <AdditionalIncludeDirectories>../../include;../ExternalAPI;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ </ResourceCompile>
+ <Bscmake>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ </Bscmake>
+ <Link>
+ <SuppressStartupBanner>true</SuppressStartupBanner>
+ <LinkDLL>true</LinkDLL>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <SubSystem>Console</SubSystem>
+ <IgnoreSpecificDefaultLibraries>uuid.lib;OLDNAMES;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
+ <ModuleDefinitionFile>flags.def</ModuleDefinitionFile>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <BaseAddress>0x24200000</BaseAddress>
+ <AdditionalDependencies>comctl32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <AdditionalOptions> /mapinfo:lines</AdditionalOptions>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="countrylistext.c">
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> /opt:nowin98 /opt:nowin98 </AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'"> /opt:ref /opt:nowin98 /opt:ref /opt:nowin98 </AdditionalOptions>
+ </ClCompile>
+ <ClCompile Include="extraimg.c">
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> /opt:nowin98 /opt:nowin98 </AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'"> /opt:ref /opt:nowin98 /opt:ref /opt:nowin98 </AdditionalOptions>
+ </ClCompile>
+ <ClCompile Include="huffman.c">
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> /opt:nowin98 /opt:nowin98 </AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'"> /opt:ref /opt:nowin98 /opt:ref /opt:nowin98 </AdditionalOptions>
+ </ClCompile>
+ <ClCompile Include="icons.c">
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> /opt:nowin98 /opt:nowin98 </AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'"> /opt:ref /opt:nowin98 /opt:ref /opt:nowin98 </AdditionalOptions>
+ </ClCompile>
+ <ClCompile Include="ip2country.c">
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> /opt:nowin98 /opt:nowin98 </AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'"> /opt:ref /opt:nowin98 /opt:ref /opt:nowin98 </AdditionalOptions>
+ </ClCompile>
+ <ClCompile Include="main.c">
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> /opt:nowin98 /opt:nowin98 </AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'"> /opt:ref /opt:nowin98 /opt:ref /opt:nowin98 </AdditionalOptions>
+ </ClCompile>
+ <ClCompile Include="utils.c">
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> /opt:nowin98 /opt:nowin98 </AdditionalOptions>
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release Unicode|Win32'"> /opt:ref /opt:nowin98 /opt:ref /opt:nowin98 </AdditionalOptions>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="flags.h" />
+ <ClInclude Include="m_flags.h" />
+ <ClInclude Include="resource.h" />
+ <ClInclude Include="version.h" />
+ <ClInclude Include="include\m_clui.h" />
+ <ClInclude Include="include\m_cluiframes.h" />
+ <ClInclude Include="include\m_database.h" />
+ <ClInclude Include="include\m_icolib.h" />
+ <ClInclude Include="include\m_langpack.h" />
+ <ClInclude Include="include\m_message.h" />
+ <ClInclude Include="include\m_options.h" />
+ <ClInclude Include="include\m_plugins.h" />
+ <ClInclude Include="include\m_skin.h" />
+ <ClInclude Include="include\m_system.h" />
+ <ClInclude Include="include\m_utils.h" />
+ <ClInclude Include="include\newpluginapi.h" />
+ <ClInclude Include="include\statusmodes.h" />
+ <ClInclude Include="include\win2k.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="res\flags.bmp" />
+ <CustomBuild Include="res\ip-to-country.bin">
+ <FileType>Document</FileType>
+ </CustomBuild>
+ <CustomBuild Include="docs\Flags-Developer.txt" />
+ <CustomBuild Include="docs\Flags-License.txt" />
+ <CustomBuild Include="docs\Flags-Readme.txt" />
+ <CustomBuild Include="docs\Flags-Translation.txt" />
+ <CustomBuild Include="m_flags.inc">
+ <FileType>Document</FileType>
+ </CustomBuild>
+ <CustomBuild Include="Info_Src.txt" />
+ <CustomBuild Include="License_Appendix.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/CountryFlags/flags.vcxproj.filters b/plugins/CountryFlags/flags.vcxproj.filters
new file mode 100644
index 0000000000..c06f9db005
--- /dev/null
+++ b/plugins/CountryFlags/flags.vcxproj.filters
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{2e34a165-959f-4051-80ea-a8e9d3ffe09a}</UniqueIdentifier>
+ <Extensions>cpp;c;cxx;rc;def;r;odl;idl;hpj;bat</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{d5658bf6-af27-43e5-b3f8-4bc19ac22032}</UniqueIdentifier>
+ <Extensions>h;hpp;hxx;hm;inl</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{d26bc05b-c5a5-4dfc-88a9-1c9e7da444ad}</UniqueIdentifier>
+ <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+ </Filter>
+ <Filter Include="Documentation">
+ <UniqueIdentifier>{71089b54-009a-4229-868a-c90b5e0b350e}</UniqueIdentifier>
+ <Extensions>txt</Extensions>
+ </Filter>
+ <Filter Include="SDK">
+ <UniqueIdentifier>{0b81b17c-89f3-4558-a861-4385827dddb3}</UniqueIdentifier>
+ <Extensions>*.h</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="countrylistext.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="extraimg.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="huffman.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="icons.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="ip2country.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="main.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="utils.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="flags.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="m_flags.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Resource Files</Filter>
+ </ClInclude>
+ <ClInclude Include="version.h">
+ <Filter>Resource Files</Filter>
+ </ClInclude>
+ <ClInclude Include="include\m_clui.h">
+ <Filter>SDK</Filter>
+ </ClInclude>
+ <ClInclude Include="include\m_cluiframes.h">
+ <Filter>SDK</Filter>
+ </ClInclude>
+ <ClInclude Include="include\m_database.h">
+ <Filter>SDK</Filter>
+ </ClInclude>
+ <ClInclude Include="include\m_icolib.h">
+ <Filter>SDK</Filter>
+ </ClInclude>
+ <ClInclude Include="include\m_langpack.h">
+ <Filter>SDK</Filter>
+ </ClInclude>
+ <ClInclude Include="include\m_message.h">
+ <Filter>SDK</Filter>
+ </ClInclude>
+ <ClInclude Include="include\m_options.h">
+ <Filter>SDK</Filter>
+ </ClInclude>
+ <ClInclude Include="include\m_plugins.h">
+ <Filter>SDK</Filter>
+ </ClInclude>
+ <ClInclude Include="include\m_skin.h">
+ <Filter>SDK</Filter>
+ </ClInclude>
+ <ClInclude Include="include\m_system.h">
+ <Filter>SDK</Filter>
+ </ClInclude>
+ <ClInclude Include="include\m_utils.h">
+ <Filter>SDK</Filter>
+ </ClInclude>
+ <ClInclude Include="include\newpluginapi.h">
+ <Filter>SDK</Filter>
+ </ClInclude>
+ <ClInclude Include="include\statusmodes.h">
+ <Filter>SDK</Filter>
+ </ClInclude>
+ <ClInclude Include="include\win2k.h">
+ <Filter>SDK</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="resource.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <CustomBuild Include="res\flags.bmp">
+ <Filter>Resource Files</Filter>
+ </CustomBuild>
+ <CustomBuild Include="res\ip-to-country.bin">
+ <Filter>Resource Files</Filter>
+ </CustomBuild>
+ <CustomBuild Include="docs\Flags-Developer.txt">
+ <Filter>Documentation</Filter>
+ </CustomBuild>
+ <CustomBuild Include="docs\Flags-License.txt">
+ <Filter>Documentation</Filter>
+ </CustomBuild>
+ <CustomBuild Include="docs\Flags-Readme.txt">
+ <Filter>Documentation</Filter>
+ </CustomBuild>
+ <CustomBuild Include="docs\Flags-Translation.txt">
+ <Filter>Documentation</Filter>
+ </CustomBuild>
+ <CustomBuild Include="m_flags.inc">
+ <Filter>Documentation</Filter>
+ </CustomBuild>
+ <CustomBuild Include="Info_Src.txt">
+ <Filter>Documentation</Filter>
+ </CustomBuild>
+ <CustomBuild Include="License_Appendix.txt">
+ <Filter>Documentation</Filter>
+ </CustomBuild>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/plugins/CountryFlags/huffman.c b/plugins/CountryFlags/huffman.c
new file mode 100644
index 0000000000..f05e82113e
--- /dev/null
+++ b/plugins/CountryFlags/huffman.c
@@ -0,0 +1,506 @@
+/*************************************************************************
+* Name: huffman.c
+* Author: Marcus Geelnard
+* Description: Huffman coder/decoder implementation.
+* Reentrant: Yes
+*
+* This is a very straight forward implementation of a Huffman coder and
+* decoder.
+*
+* Primary flaws with this primitive implementation are:
+* - Slow bit stream implementation
+* - Maximum tree depth of 32 (the coder aborts if any code exceeds a
+* size of 32 bits). If I'm not mistaking, this should not be possible
+* unless the input buffer is larger than 2^32 bytes, which is not
+* supported by the coder anyway (max 2^32-1 bytes can be specified with
+* an unsigned 32-bit integer).
+*
+* On the other hand, there are a few advantages of this implementation:
+* - The Huffman tree is stored in a very compact form, requiring only
+* 10 bits per symbol (for 8 bit symbols), meaning a maximum of 320
+* bytes overhead.
+* - The code should be fairly easy to follow, if you are familiar with
+* how the Huffman compression algorithm works.
+*
+* Possible improvements (probably not worth it):
+* - Partition the input data stream into blocks, where each block has
+* its own Huffman tree. With variable block sizes, it should be
+* possible to find locally optimal Huffman trees, which in turn could
+* reduce the total size.
+* - Allow for a few different predefined Huffman trees, which could
+* reduce the size of a block even further.
+*-------------------------------------------------------------------------
+* Copyright (c) 2003-2006 Marcus Geelnard
+*
+* This software is provided 'as-is', without any express or implied
+* warranty. In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+* claim that you wrote the original software. If you use this software
+* in a product, an acknowledgment in the product documentation would
+* be appreciated but is not required.
+*
+* 2. Altered source versions must be plainly marked as such, and must not
+* be misrepresented as being the original software.
+*
+* 3. This notice may not be removed or altered from any source
+* distribution.
+*
+* Marcus Geelnard
+* marcus.geelnard at home.se
+*************************************************************************/
+
+
+/*************************************************************************
+* Types used for Huffman coding
+*************************************************************************/
+
+typedef struct {
+ unsigned char *BytePtr;
+ unsigned int BitPos;
+} huff_bitstream_t;
+
+typedef struct {
+ int Symbol;
+ unsigned int Count;
+ unsigned int Code;
+ unsigned int Bits;
+} huff_sym_t;
+
+typedef struct huff_encodenode_struct huff_encodenode_t;
+
+struct huff_encodenode_struct {
+ huff_encodenode_t *ChildA, *ChildB;
+ int Count;
+ int Symbol;
+};
+
+typedef struct huff_decodenode_struct huff_decodenode_t;
+
+struct huff_decodenode_struct {
+ huff_decodenode_t *ChildA, *ChildB;
+ int Symbol;
+};
+
+
+/*************************************************************************
+* Constants for Huffman decoding
+*************************************************************************/
+
+/* The maximum number of nodes in the Huffman tree is 2^(8+1)-1 = 511 */
+#define MAX_TREE_NODES 511
+
+
+/*************************************************************************
+* _Huffman_InitBitstream() - Initialize a bitstream.
+*************************************************************************/
+
+static void _Huffman_InitBitstream( huff_bitstream_t *stream,
+ unsigned char *buf )
+{
+ stream->BytePtr = buf;
+ stream->BitPos = 0;
+}
+
+
+/*************************************************************************
+* _Huffman_ReadBit() - Read one bit from a bitstream.
+*************************************************************************/
+
+static unsigned int _Huffman_ReadBit( huff_bitstream_t *stream )
+{
+ unsigned int x, bit;
+ unsigned char *buf;
+
+ /* Get current stream state */
+ buf = stream->BytePtr;
+ bit = stream->BitPos;
+
+ /* Extract bit */
+ x = (*buf & (1<<(7-bit))) ? 1 : 0;
+ bit = (bit+1) & 7;
+ if( !bit )
+ {
+ ++ buf;
+ }
+
+ /* Store new stream state */
+ stream->BitPos = bit;
+ stream->BytePtr = buf;
+
+ return x;
+}
+
+
+/*************************************************************************
+* _Huffman_Read8Bits() - Read eight bits from a bitstream.
+*************************************************************************/
+
+static unsigned int _Huffman_Read8Bits( huff_bitstream_t *stream )
+{
+ unsigned int x, bit;
+ unsigned char *buf;
+
+ /* Get current stream state */
+ buf = stream->BytePtr;
+ bit = stream->BitPos;
+
+ /* Extract byte */
+ x = (*buf << bit) | (buf[1] >> (8-bit));
+ ++ buf;
+
+ /* Store new stream state */
+ stream->BytePtr = buf;
+
+ return x;
+}
+
+
+/*************************************************************************
+* _Huffman_WriteBits() - Write bits to a bitstream.
+*************************************************************************/
+
+#ifdef HUFFMAN_ENCODE
+static void _Huffman_WriteBits( huff_bitstream_t *stream, unsigned int x,
+ unsigned int bits )
+{
+ unsigned int bit, count;
+ unsigned char *buf;
+ unsigned int mask;
+
+ /* Get current stream state */
+ buf = stream->BytePtr;
+ bit = stream->BitPos;
+
+ /* Append bits */
+ mask = 1 << (bits-1);
+ for( count = 0; count < bits; ++ count )
+ {
+ *buf = (unsigned char)((*buf & (0xff^(1<<(7-bit)))) +
+ ((x & mask ? 1 : 0) << (7-bit)));
+ x <<= 1;
+ bit = (bit+1) & 7;
+ if( !bit )
+ {
+ ++ buf;
+ }
+ }
+
+ /* Store new stream state */
+ stream->BytePtr = buf;
+ stream->BitPos = bit;
+}
+#endif
+
+
+/*************************************************************************
+* _Huffman_Hist() - Calculate (sorted) histogram for a block of data.
+*************************************************************************/
+
+#ifdef HUFFMAN_ENCODE
+static void _Huffman_Hist( unsigned char *in, huff_sym_t *sym,
+ unsigned int size )
+{
+ int k;
+
+ /* Clear/init histogram */
+ for( k = 0; k < 256; ++ k )
+ {
+ sym[k].Symbol = k;
+ sym[k].Count = 0;
+ sym[k].Code = 0;
+ sym[k].Bits = 0;
+ }
+
+ /* Build histogram */
+ for( k = size; k; -- k )
+ {
+ sym[*in ++].Count ++;
+ }
+}
+#endif
+
+
+/*************************************************************************
+* _Huffman_StoreTree() - Store a Huffman tree in the output stream and
+* in a look-up-table (a symbol array).
+*************************************************************************/
+
+#ifdef HUFFMAN_ENCODE
+static void _Huffman_StoreTree( huff_encodenode_t *node, huff_sym_t *sym,
+ huff_bitstream_t *stream, unsigned int code, unsigned int bits )
+{
+ unsigned int sym_idx;
+
+ /* Is this a leaf node? */
+ if( node->Symbol >= 0 )
+ {
+ /* Append symbol to tree description */
+ _Huffman_WriteBits( stream, 1, 1 );
+ _Huffman_WriteBits( stream, node->Symbol, 8 );
+
+ /* Find symbol index */
+ for( sym_idx = 0; sym_idx < 256; ++ sym_idx )
+ {
+ if( sym[sym_idx].Symbol == node->Symbol ) break;
+ }
+
+ /* Store code info in symbol array */
+ sym[sym_idx].Code = code;
+ sym[sym_idx].Bits = bits;
+ return;
+ }
+ else
+ {
+ /* This was not a leaf node */
+ _Huffman_WriteBits( stream, 0, 1 );
+ }
+
+ /* Branch A */
+ _Huffman_StoreTree( node->ChildA, sym, stream, (code<<1)+0, bits+1 );
+
+ /* Branch B */
+ _Huffman_StoreTree( node->ChildB, sym, stream, (code<<1)+1, bits+1 );
+}
+#endif
+
+
+/*************************************************************************
+* _Huffman_MakeTree() - Generate a Huffman tree.
+*************************************************************************/
+
+#ifdef HUFFMAN_ENCODE
+static void _Huffman_MakeTree( huff_sym_t *sym, huff_bitstream_t *stream )
+{
+ huff_encodenode_t nodes[MAX_TREE_NODES], *node_1, *node_2, *root;
+ unsigned int k, num_symbols, nodes_left, next_idx;
+
+ /* Initialize all leaf nodes */
+ num_symbols = 0;
+ for( k = 0; k < 256; ++ k )
+ {
+ if( sym[k].Count > 0 )
+ {
+ nodes[num_symbols].Symbol = sym[k].Symbol;
+ nodes[num_symbols].Count = sym[k].Count;
+ nodes[num_symbols].ChildA = (huff_encodenode_t *) 0;
+ nodes[num_symbols].ChildB = (huff_encodenode_t *) 0;
+ ++ num_symbols;
+ }
+ }
+
+ /* Build tree by joining the lightest nodes until there is only
+ one node left (the root node). */
+ root = (huff_encodenode_t *) 0;
+ nodes_left = num_symbols;
+ next_idx = num_symbols;
+ while( nodes_left > 1 )
+ {
+ /* Find the two lightest nodes */
+ node_1 = (huff_encodenode_t *) 0;
+ node_2 = (huff_encodenode_t *) 0;
+ for( k = 0; k < next_idx; ++ k )
+ {
+ if( nodes[k].Count > 0 )
+ {
+ if( !node_1 || (nodes[k].Count <= node_1->Count) )
+ {
+ node_2 = node_1;
+ node_1 = &nodes[k];
+ }
+ else if( !node_2 || (nodes[k].Count <= node_2->Count) )
+ {
+ node_2 = &nodes[k];
+ }
+ }
+ }
+
+ /* Join the two nodes into a new parent node */
+ root = &nodes[next_idx];
+ root->ChildA = node_1;
+ root->ChildB = node_2;
+ root->Count = node_1->Count + node_2->Count;
+ root->Symbol = -1;
+ node_1->Count = 0;
+ node_2->Count = 0;
+ ++ next_idx;
+ -- nodes_left;
+ }
+
+ /* Store the tree in the output stream, and in the sym[] array (the
+ latter is used as a look-up-table for faster encoding) */
+ if( root )
+ {
+ _Huffman_StoreTree( root, sym, stream, 0, 0 );
+ }
+ else
+ {
+ /* Special case: only one symbol => no binary tree */
+ root = &nodes[0];
+ _Huffman_StoreTree( root, sym, stream, 0, 1 );
+ }
+}
+#endif
+
+
+/*************************************************************************
+* _Huffman_RecoverTree() - Recover a Huffman tree from a bitstream.
+*************************************************************************/
+
+static huff_decodenode_t * _Huffman_RecoverTree( huff_decodenode_t *nodes,
+ huff_bitstream_t *stream, unsigned int *nodenum )
+{
+ huff_decodenode_t * this_node;
+
+ /* Pick a node from the node array */
+ this_node = &nodes[*nodenum];
+ *nodenum = *nodenum + 1;
+
+ /* Clear the node */
+ this_node->Symbol = -1;
+ this_node->ChildA = (huff_decodenode_t *) 0;
+ this_node->ChildB = (huff_decodenode_t *) 0;
+
+ /* Is this a leaf node? */
+ if( _Huffman_ReadBit( stream ) )
+ {
+ /* Get symbol from tree description and store in lead node */
+ this_node->Symbol = _Huffman_Read8Bits( stream );
+
+ return this_node;
+ }
+
+ /* Get branch A */
+ this_node->ChildA = _Huffman_RecoverTree( nodes, stream, nodenum );
+
+ /* Get branch B */
+ this_node->ChildB = _Huffman_RecoverTree( nodes, stream, nodenum );
+
+ return this_node;
+}
+
+
+
+/*************************************************************************
+* PUBLIC FUNCTIONS *
+*************************************************************************/
+
+
+/*************************************************************************
+* Huffman_Compress() - Compress a block of data using a Huffman coder.
+* in - Input (uncompressed) buffer.
+* out - Output (compressed) buffer. This buffer must be 384 bytes
+* larger than the input buffer.
+* insize - Number of input bytes.
+* The function returns the size of the compressed data.
+*************************************************************************/
+
+#ifdef HUFFMAN_ENCODE
+int Huffman_Compress( unsigned char *in, unsigned char *out,
+ unsigned int insize )
+{
+ huff_sym_t sym[256], tmp;
+ huff_bitstream_t stream;
+ unsigned int k, total_bytes, swaps, symbol;
+
+ /* Do we have anything to compress? */
+ if( insize < 1 ) return 0;
+
+ /* Initialize bitstream */
+ _Huffman_InitBitstream( &stream, out );
+
+ /* Calculate and sort histogram for input data */
+ _Huffman_Hist( in, sym, insize );
+
+ /* Build Huffman tree */
+ _Huffman_MakeTree( sym, &stream );
+
+ /* Sort histogram - first symbol first (bubble sort) */
+ do
+ {
+ swaps = 0;
+ for( k = 0; k < 255; ++ k )
+ {
+ if( sym[k].Symbol > sym[k+1].Symbol )
+ {
+ tmp = sym[k];
+ sym[k] = sym[k+1];
+ sym[k+1] = tmp;
+ swaps = 1;
+ }
+ }
+ }
+ while( swaps );
+
+ /* Encode input stream */
+ for( k = 0; k < insize; ++ k )
+ {
+ symbol = in[k];
+ _Huffman_WriteBits( &stream, sym[symbol].Code,
+ sym[symbol].Bits );
+ }
+
+ /* Calculate size of output data */
+ total_bytes = (int)(stream.BytePtr - out);
+ if( stream.BitPos > 0 )
+ {
+ ++ total_bytes;
+ }
+
+ return total_bytes;
+}
+#endif
+
+
+/*************************************************************************
+* Huffman_Uncompress() - Uncompress a block of data using a Huffman
+* decoder.
+* in - Input (compressed) buffer.
+* out - Output (uncompressed) buffer. This buffer must be large
+* enough to hold the uncompressed data.
+* insize - Number of input bytes.
+* outsize - Number of output bytes.
+*************************************************************************/
+
+void Huffman_Uncompress( unsigned char *in, unsigned char *out,
+ unsigned int insize, unsigned int outsize )
+{
+ huff_decodenode_t nodes[MAX_TREE_NODES], *root, *node;
+ huff_bitstream_t stream;
+ unsigned int k, node_count;
+ unsigned char *buf;
+
+ /* Do we have anything to decompress? */
+ if( insize < 1 ) return;
+
+ /* Initialize bitstream */
+ _Huffman_InitBitstream( &stream, in );
+
+ /* Recover Huffman tree */
+ node_count = 0;
+ root = _Huffman_RecoverTree( nodes, &stream, &node_count );
+
+ /* Decode input stream */
+ buf = out;
+ for( k = 0; k < outsize; ++ k )
+ {
+ /* Traverse tree until we find a matching leaf node */
+ node = root;
+ while( node->Symbol < 0 )
+ {
+ /* Get next node */
+ if( _Huffman_ReadBit( &stream ) )
+ node = node->ChildB;
+ else
+ node = node->ChildA;
+ }
+
+ /* We found the matching leaf node and have the symbol */
+ *buf ++ = (unsigned char) node->Symbol;
+ }
+}
diff --git a/plugins/CountryFlags/icons.c b/plugins/CountryFlags/icons.c
new file mode 100644
index 0000000000..9611eb0b78
--- /dev/null
+++ b/plugins/CountryFlags/icons.c
@@ -0,0 +1,284 @@
+/*
+Miranda IM Country Flags Plugin
+Copyright (C) 2006-1007 H. Herkenrath
+
+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 (Flags-License.txt); if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "flags.h"
+
+extern HINSTANCE hInst;
+extern int nCountriesCount;
+extern struct CountryListEntry *countries;
+static HANDLE hServiceLoadIcon,hServiceCreateMergedIcon;
+
+/************************* Bitmap Access **************************/
+
+static HANDLE *phIconHandles;
+
+static int FASTCALL CountryNumberToBitmapIndex(int countryNumber)
+{
+ /* country number indices (same order as in flags.bmp) */
+ const int BitmapIndexMap[232]={
+ 0, 1, 7, 20, 27, 30, 31, 32, 33, 34, 36, 39, 40, 41, 43, 44, 45, 46, 47, 48,
+ 49, 51, 52, 53, 54, 55, 56, 57, 58, 60, 61, 62, 63, 64, 65, 66, 81, 82, 84, 86,
+ 90, 91, 92, 93, 94, 95, 98, 101, 102, 103, 104, 105, 106, 107, 178, 108, 109, 110, 111, 112,
+ 113, 116, 117, 118, 121, 122, 123, 212, 213, 216, 218, 220, 221, 222, 223, 224, 225, 226, 227, 228,
+ 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 248, 249,
+ 250, 251, 252, 253, 254, 255, 256, 257, 258, 260, 261, 263, 264, 265, 266, 267, 268, 269, 290, 291,
+ 297, 298, 299, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 370, 371, 372, 373, 374, 375, 376,
+ 377, 378, 379, 380, 381, 382, 385, 386, 387, 389, 420, 421, 441, 442, 500, 501, 502, 503, 504, 505,
+ 506, 507, 508, 509, 590, 591, 592, 593, 595, 596, 597, 598, 599, 670, 671, 672, 673, 674, 675, 676,
+ 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 705, 706, 708, 709,
+ 711, 850, 852, 853, 855, 856, 880, 886, 960, 961, 962, 963, 964, 965, 966, 967, 968, 971, 972, 973,
+ 974, 975, 976, 977, 994, 995,1141,2691,3811,4101,6101,6722
+ };
+ /* shared flags by multiple countries */
+ switch(countryNumber) {
+ case 262: /* Reunion Island */
+ case 594: /* French Guiana */
+ case 5901: /* French Antilles */
+ countryNumber=33; /* France */
+ break;
+ case 120: /* Barbuda */
+ countryNumber=102; /* Antigua and Barbuda */
+ break;
+ case 6702: /* Tinian Island */
+ case 6701: /* Rota Island */
+ countryNumber=670; /* Saipan Island (Northern Mariana Islands) */
+ break;
+ case 115: /* Saint Kitts */
+ case 114: /* Nevis */
+ countryNumber=1141; /* Saint Kitts and Nevis */
+ break;
+ case 247: /* Ascension Island */
+ countryNumber=44; /* United Kingdom */
+ break;
+ case 6721: /* Australian Antarctic Territory */
+ countryNumber=61; /* Australia */
+ break;
+ case 5399: /* Guantanamo Bay */
+ countryNumber=1; /* USA */
+ }
+ /* binary search in index array */
+ { int low=0,i,high;
+ high=SIZEOF(BitmapIndexMap)-1;
+ if(countryNumber<=BitmapIndexMap[high])
+ while(low<=high) {
+ i=low+((high-low)/2);
+ /* never happens */
+ if(i<0 || i>=SIZEOF(BitmapIndexMap)) DebugBreak();
+ if(BitmapIndexMap[i]==countryNumber) return i;
+ if(countryNumber>BitmapIndexMap[i]) low=i+1;
+ else high=i-1;
+ }
+ }
+ /* Other,Unknown,Unspecified */
+ return 0;
+}
+
+// return value needs to be released using DestroyIcon()
+// only operates on color icons, which isn't a problem here
+static HICON FASTCALL ResizeIconCentered(HICON hIcon,int cx,int cy)
+{
+ HICON hResIcon=NULL;
+ ICONINFO icoi;
+ BITMAP bm;
+ register HDC hdc;
+ HBITMAP hbmPrev,hbm;
+ POINT pt;
+ hdc=CreateCompatibleDC(NULL);
+ if(hdc!=NULL) {
+ if(GetIconInfo(hIcon,&icoi)) {
+ if(GetObject(icoi.hbmColor,sizeof(bm),&bm) && bm.bmWidth<=cx && bm.bmHeight<=cy) {
+ pt.x=(cx-bm.bmWidth)/2;
+ pt.y=(cy-bm.bmHeight)/2;
+ hbmPrev=SelectObject(hdc,icoi.hbmColor);
+ if(hbmPrev!=NULL) { /* error on select? */
+ hbm=icoi.hbmColor;
+ icoi.hbmColor=CreateCompatibleBitmap(hdc,cx,cy);
+ if(icoi.hbmColor!=NULL)
+ if(SelectObject(hdc,icoi.hbmColor)!=NULL) { /* error on select? */
+ DeleteObject(hbm); /* delete prev color (XOR) */
+ if(BitBlt(hdc,0,0,cx,cy,NULL,0,0,BLACKNESS)) /* transparency: AND=0, XOR=1 */
+ if(DrawIconEx(hdc,pt.x,pt.y,hIcon,bm.bmWidth,bm.bmHeight,0,NULL,DI_IMAGE|DI_NOMIRROR)) {
+ if(SelectObject(hdc,icoi.hbmMask)!=NULL) { /* error on select? */
+ hbm=icoi.hbmMask;
+ icoi.hbmMask=CreateBitmap(cx,cy,1,1,NULL); /* mono */
+ if(icoi.hbmMask!=NULL)
+ if(SelectObject(hdc,icoi.hbmMask)!=NULL) { /* error on select? */
+ DeleteObject(hbm); /* delete prev mask (AND) */
+ if(BitBlt(hdc,0,0,cx,cy,NULL,0,0,WHITENESS)) /* transparency: AND=0, XOR=1 */
+ if(DrawIconEx(hdc,pt.x,pt.y,hIcon,0,0,0,NULL,DI_MASK|DI_NOMIRROR)) {
+ SelectObject(hdc,hbmPrev);
+ hResIcon=CreateIconIndirect(&icoi); /* bitmaps must not be selected */
+ }
+ }
+ }
+ }
+ }
+ SelectObject(hdc,hbmPrev);
+ }
+ }
+ DeleteObject(icoi.hbmColor);
+ DeleteObject(icoi.hbmMask);
+ }
+ DeleteDC(hdc);
+ }
+ return hResIcon;
+}
+
+/************************* Utils **********************************/
+
+HICON FASTCALL LoadFlagIcon(int countryNumber)
+{
+ char szId[20],*szCountry;
+ /* create identifier */
+ szCountry=(char*)CallService(MS_UTILS_GETCOUNTRYBYNUMBER,countryNumber,0);
+ if(szCountry==NULL) szCountry=(char*)CallService(MS_UTILS_GETCOUNTRYBYNUMBER,countryNumber=0xFFFF,0);
+ wsprintfA(szId,(countryNumber==0xFFFF)?"%s0x%X":"%s%i","flags_",countryNumber); /* buffer safe */
+ return (HICON)CallService(MS_SKIN2_GETICON,0,(LPARAM)szId);
+}
+
+int FASTCALL CountryNumberToIndex(int countryNumber)
+{
+ int i,nf=0;
+ for(i=0;i<nCountriesCount;++i) {
+ if(countries[i].id==countryNumber) return i;
+ if(countries[i].id==0xFFFF) nf=i;
+ }
+ return nf; /* Unknown */
+
+}
+
+/************************* Services *******************************/
+
+static int ServiceLoadFlagIcon(WPARAM wParam,LPARAM lParam)
+{
+ /* return handle */
+ if((BOOL)lParam) {
+ if(phIconHandles==NULL) return (int)(HANDLE)NULL;
+ return (int)phIconHandles[CountryNumberToIndex((int)wParam)];
+ }
+ /* return icon */
+ return (int)LoadFlagIcon(wParam);
+}
+
+static int ServiceCreateMergedFlagIcon(WPARAM wParam,LPARAM lParam)
+{
+ HICON hUpperIcon,hLowerIcon;
+ ICONINFO icoi;
+ BITMAP bm;
+ HDC hdc;
+ POINT aptTriangle[3];
+ HICON hIcon=NULL;
+ HRGN hrgn;
+ HBITMAP hbmPrev;
+ /* load both icons */
+ hLowerIcon=(HICON)ServiceLoadFlagIcon((WPARAM)lParam,0);
+ if(hLowerIcon==NULL) return (int)(HICON)NULL;
+ hUpperIcon=(HICON)ServiceLoadFlagIcon(wParam,0);
+ /* merge them */
+ if(GetIconInfo(hLowerIcon,&icoi)) {
+ if(hUpperIcon!=NULL && GetObject(icoi.hbmColor,sizeof(bm),&bm)) {
+ hdc=CreateCompatibleDC(NULL);
+ if(hdc!=NULL) {
+ ZeroMemory(&aptTriangle,sizeof(aptTriangle));
+ aptTriangle[1].y=bm.bmHeight-1;
+ aptTriangle[2].x=bm.bmWidth-1;
+ hrgn=CreatePolygonRgn(aptTriangle,SIZEOF(aptTriangle),WINDING);
+ if(hrgn!=NULL) {
+ SelectClipRgn(hdc,hrgn);
+ DeleteObject(hrgn);
+ hbmPrev=SelectObject(hdc,icoi.hbmColor);
+ if(hbmPrev!=NULL) { /* error on select? */
+ if(DrawIconEx(hdc,0,0,hUpperIcon,bm.bmWidth,bm.bmHeight,0,NULL,DI_NOMIRROR|DI_IMAGE))
+ if(SelectObject(hdc,icoi.hbmMask)!=NULL) /* error on select? */
+ DrawIconEx(hdc,0,0,hUpperIcon,bm.bmWidth,bm.bmHeight,0,NULL,DI_NOMIRROR|DI_MASK);
+ SelectObject(hdc,hbmPrev);
+ }
+ DeleteObject(hrgn);
+ }
+ DeleteDC(hdc);
+ }
+ }
+ /* create icon */
+ hIcon=CreateIconIndirect(&icoi);
+ DeleteObject(icoi.hbmColor);
+ DeleteObject(icoi.hbmMask);
+ }
+ return (int)hIcon;
+}
+
+/************************* Misc ***********************************/
+
+void InitIcons(void)
+{
+ HIMAGELIST himl;
+ SKINICONDESC sid;
+ char szId[20];
+ int i,index;
+ HICON hIcon;
+#if defined(_UNICODE)
+ WCHAR szName[64];
+ LCID locale;
+ locale=(LCID)CallService(MS_LANGPACK_GETLOCALE,0,0);
+#endif
+
+ /* register icons */
+ ZeroMemory(&sid,sizeof(sid));
+ sid.cbSize=sizeof(sid);
+ sid.pszName=szId;
+ sid.cx=GetSystemMetrics(SM_CXSMICON);
+ sid.cy=GetSystemMetrics(SM_CYSMICON);
+ sid.flags=SIDF_SORTED|SIDF_TCHAR;
+ sid.ptszSection=TranslateT("Country Flags");
+ /* all those flag icons do not need any transparency mask (flags are always opaque),
+ * storing them in a large bitmap to reduce file size */
+ himl=ImageList_LoadImage(hInst,MAKEINTRESOURCE(IDB_FLAGS),sid.cx,0,CLR_NONE,IMAGE_BITMAP,LR_CREATEDIBSECTION);
+ if(himl!=NULL) {
+ phIconHandles=(HANDLE*)mir_alloc(nCountriesCount*sizeof(HANDLE));
+ if(phIconHandles!=NULL)
+ for(i=0;i<nCountriesCount;++i) {
+#if defined(_UNICODE)
+ MultiByteToWideChar(locale,0,countries[i].szName,-1,szName,SIZEOF(szName));
+ szName[SIZEOF(szName)-1]=L'\0';
+ sid.pwszDescription=TranslateW(szName);
+#else
+ sid.pszDescription=Translate(countries[i].szName);
+#endif
+ /* create identifier */
+ wsprintfA(szId,(countries[i].id==0xFFFF)?"%s0x%X":"%s%i","flags_",countries[i].id); /* buffer safe */
+ index=CountryNumberToBitmapIndex(countries[i].id);
+ /* create icon */
+ hIcon=ImageList_GetIcon(himl,index,ILD_NORMAL);
+ sid.hDefaultIcon=(hIcon!=NULL)?ResizeIconCentered(hIcon,sid.cx,sid.cy):NULL;
+ if(hIcon!=NULL) DestroyIcon(hIcon);
+ index=CountryNumberToIndex(countries[i].id);
+ phIconHandles[index]=(HANDLE)CallService(MS_SKIN2_ADDICON,0,(LPARAM)&sid);
+ if(sid.hDefaultIcon!=NULL) DestroyIcon(sid.hDefaultIcon);
+ }
+ ImageList_Destroy(himl);
+ }
+ /* create services */
+ hServiceLoadIcon=CreateServiceFunction(MS_FLAGS_LOADFLAGICON,ServiceLoadFlagIcon);
+ hServiceCreateMergedIcon=CreateServiceFunction(MS_FLAGS_CREATEMERGEDFLAGICON,ServiceCreateMergedFlagIcon);
+}
+
+void UninitIcons(void)
+{
+ DestroyServiceFunction(hServiceLoadIcon);
+ DestroyServiceFunction(hServiceCreateMergedIcon);
+}
diff --git a/plugins/CountryFlags/ip2country.c b/plugins/CountryFlags/ip2country.c
new file mode 100644
index 0000000000..eae267aaa0
--- /dev/null
+++ b/plugins/CountryFlags/ip2country.c
@@ -0,0 +1,327 @@
+/*
+Miranda IM Country Flags Plugin
+Copyright (C) 2006-2007 H. Herkenrath
+
+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 (Flags-License.txt); if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "flags.h"
+
+extern HINSTANCE hInst;
+extern int nCountriesCount;
+extern struct CountryListEntry *countries;
+static HANDLE hServiceIpToCountry;
+
+/************************* Bin Records ****************************/
+
+#define DATARECORD_SIZE (sizeof(DWORD)+sizeof(DWORD)+sizeof(WORD))
+
+// mir_free() the return value
+static BYTE* GetDataHeader(BYTE *data,DWORD cbDataSize,DWORD *pnDataRecordCount)
+{
+ BYTE *recordData;
+ /* uncompressed size stored in first DWORD */
+ *pnDataRecordCount=(*(DWORD*)data)/DATARECORD_SIZE;
+ recordData=(BYTE*)mir_alloc(*(DWORD*)data);
+ if(recordData!=NULL)
+ Huffman_Uncompress(data+sizeof(DWORD),recordData,cbDataSize-sizeof(DWORD),*(DWORD*)data);
+ return recordData;
+}
+
+static int GetDataRecord(BYTE *data,DWORD index,DWORD *pdwFrom,DWORD *pdwTo)
+{
+ data+=index*DATARECORD_SIZE;
+ *pdwFrom=*(DWORD*)data;
+ data+=sizeof(DWORD);
+ if(pdwTo!=NULL) *pdwTo=*(DWORD*)data;
+ data+=sizeof(DWORD);
+ return (int)*(WORD*)data;
+}
+
+/************************* Record Cache ***************************/
+
+static CRITICAL_SECTION csRecordCache;
+static DWORD nDataRecordsCount; /* protected by csRecordCache */
+static BYTE *dataRecords; /* protected by csRecordCache */
+
+#define UNLOADDELAY 30*1000 /* time after which the data records are being unloaded */
+
+static void CALLBACK UnloadRecordCache(LPARAM lParam)
+{
+ UNREFERENCED_PARAMETER(lParam);
+ EnterCriticalSection(&csRecordCache);
+ mir_free(dataRecords);
+ dataRecords=NULL;
+ LeaveCriticalSection(&csRecordCache);
+}
+
+// function assumes it has got the csRecordCache mutex
+static BOOL EnsureRecordCacheLoaded(BYTE **pdata,DWORD *pcount)
+{
+ HRSRC hrsrc;
+ DWORD cb;
+ EnterCriticalSection(&csRecordCache);
+ if(dataRecords==NULL) {
+ /* load record data list from resources */
+ hrsrc=FindResource(hInst,MAKEINTRESOURCE(IDR_IPTOCOUNTRY),_T("BIN"));
+ cb=SizeofResource(hInst,hrsrc);
+ dataRecords=(BYTE*)LockResource(LoadResource(hInst,hrsrc));
+ if(cb<=sizeof(DWORD) || dataRecords==NULL) { LeaveCriticalSection(&csRecordCache); return FALSE; }
+ /* uncompress record data */
+ dataRecords=GetDataHeader(dataRecords,cb,&nDataRecordsCount);
+ if(dataRecords==NULL || !nDataRecordsCount) { LeaveCriticalSection(&csRecordCache); return FALSE; }
+ }
+ *pdata=dataRecords;
+ *pcount=nDataRecordsCount;
+ return TRUE;
+}
+
+static void LeaveRecordCache(void)
+{
+ /* mark for unload */
+ CallFunctionBuffered(UnloadRecordCache,0,FALSE,UNLOADDELAY);
+ LeaveCriticalSection(&csRecordCache);
+}
+
+/************************* Services *******************************/
+
+
+int ServiceIpToCountry(WPARAM wParam,LPARAM lParam)
+{
+ BYTE *data;
+ DWORD dwFrom,dwTo;
+ DWORD low=0,i,high;
+ int id;
+ UNREFERENCED_PARAMETER(lParam);
+ if(EnsureRecordCacheLoaded(&data,&high)) {
+ /* binary search in record data */
+ GetDataRecord(data,low,&dwFrom,NULL);
+ --high;
+ if(wParam>=dwFrom) /* only search if wParam valid */
+ while(low<=high) {
+ i=low+((high-low)/2);
+ /* never happens */
+ if(i<0) DebugBreak();
+ /* analyze record */
+ id=GetDataRecord(data,i,&dwFrom,&dwTo);
+ if(dwFrom<=wParam && dwTo>=wParam) { LeaveRecordCache(); return id; }
+ if(wParam>dwTo) low=i+1;
+ else high=i-1;
+ }
+ LeaveRecordCache();
+ }
+ return 0xFFFF; /* Unknown */
+}
+
+/************************* Bin Converter **************************/
+
+#ifdef BINCONV
+#include <stdio.h>
+#include <stdlib.h>
+
+struct {
+ const char *szMir;
+ const char *szCSV;
+} static const differentCountryNames[]={
+ {"British Virgin Islands","VIRGIN ISLANDS, BRITISH"},
+ {"Brunei","BRUNEI DARUSSALAM"},
+ {"Cape Verde Islands","CAPE VERDE"},
+ {"Cocos-Keeling Islands","COCOS (KEELING) ISLANDS"},
+ {"Chile, Republic of","CHILE"},
+ {"Congo, Democratic Republic of (Zaire)","THE DEMOCRATIC REPUBLIC OF THE CONGO"},
+ {"Congo, Republic of the","CONGO"},
+ {"Cote d'Ivoire (Ivory Coast)","COTE D'IVOIRE"},
+ {"Diego Garcia","BRITISH INDIAN OCEAN TERRITORY"},
+ {"Guam, US Territory of","GUAM"},
+ {"Iran (Islamic Republic of)","ISLAMIC REPUBLIC OF IRAN"},
+ {"Korea, North","REPUBLIC OF KOREA"},
+ {"Laos","LAO PEOPLE'S DEMOCRATIC REPUBLIC"},
+ {"Reunion Island","REUNION"},
+ {"Russia","RUSSIAN FEDERATION"},
+ {"Saipan Island (Northern Mariana Islands)","NORTHERN MARIANA ISLANDS"},
+ {"Tanzania","UNITED REPUBLIC OF TANZANIA"},
+ {"USA","UNITED STATES"},
+ {"Macau","MACAO"},
+ {"Macedonia (F.Y.R.O.M.)","THE FORMER YUGOSLAV REPUBLIC OF MACEDONIA"},
+ {"Micronesia, Federated States of","FEDERATED STATES OF MICRONESIA"},
+ {"Mayotte Island","MAYOTTE"},
+ {"Moldova, Republic of","REPUBLIC OF MOLDOVA"},
+ {"Vietnam","VIET NAM"},
+ {"Virgin Islands (USA)","VIRGIN ISLANDS, U.S."},
+ {"Vatican City","HOLY SEE (VATICAN CITY STATE)"},
+ {"Serbia, Republic of","SERBIA"},
+ {"Montenegro, Republic of","MONTENEGRO"},
+};
+
+#define ALLOC_STEP (800*1024) /* approx. size of data output */
+
+struct ResizableByteBuffer {
+ BYTE *buf;
+ DWORD cbLength,cbAlloced;
+};
+
+static void AppendToByteBuffer(struct ResizableByteBuffer *buffer,const void *append,DWORD cbAppendSize)
+{
+ if(buffer->cbAlloced<=buffer->cbLength+cbAppendSize) {
+ BYTE* buf=(BYTE*)mir_realloc(buffer->buf,buffer->cbAlloced+ALLOC_STEP+cbAppendSize);
+ if(buf==NULL) return;
+ buffer->buf=buf;
+ buffer->cbAlloced+=ALLOC_STEP+cbAppendSize;
+ OutputDebugStringA("reallocating memory...\n"); /* all ascii */
+ }
+ CopyMemory(&buffer->buf[buffer->cbLength],append,cbAppendSize);
+ buffer->cbLength+=cbAppendSize;
+}
+
+static int EnumIpDataLines(const char *pszFileCSV,const char *pszFileOut)
+{
+ FILE *fp;
+ char line[1024],out[512],*pszFrom,*pszTo,*pszTwo,*pszCountry,*buf;
+ int i,j;
+ DWORD dwOut;
+ WORD wOut;
+ struct ResizableByteBuffer buffer;
+
+ ZeroMemory(&buffer,sizeof(buffer));
+ fp=fopen(pszFileCSV,"rt");
+ if(fp!=NULL) {
+ OutputDebugStringA("Running IP data convert...\n"); /* all ascii */
+ while(!feof(fp)) {
+ if(fgets(line,sizeof(line),fp)==NULL) break;
+ /* get line data */
+ pszFrom=line+1;
+ pszTo=strchr(pszFrom,',');
+ *(pszTo-1)='\0'; pszTo+=2;
+ pszTwo=strchr(pszTo,',');
+ *(pszTwo-1)='\0'; pszTwo+=2;
+ pszCountry=strchr(pszTwo,',')+1;
+ pszCountry=strchr(pszCountry,',')+2;
+ buf=strchr(pszCountry,'"');
+ *buf=pszTwo[2]='\0';
+ /* corrections */
+ if(!lstrcmpi(pszCountry,"ANTARCTICA")) continue;
+ if(!lstrcmpi(pszCountry,"TIMOR-LESTE")) continue;
+ if(!lstrcmpi(pszCountry,"PALESTINIAN TERRITORY, OCCUPIED"))
+ lstrcpy(pszCountry,"ISRAEL");
+ else if(!lstrcmpi(pszCountry,"UNITED STATES MINOR OUTLYING ISLANDS"))
+ lstrcpy(pszCountry,"UNITED STATES");
+ else if(!lstrcmpi(pszCountry,"SOUTH GEORGIA AND THE SOUTH SANDWICH ISLANDS"))
+ lstrcpy(pszCountry,"UNITED KINGDOM");
+ else if(!lstrcmpi(pszTwo,"JE")) /* map error */
+ lstrcpy(pszCountry,"UNITED KINGDOM");
+ else if(!lstrcmpi(pszTwo,"AX")) /* Åland Island belongs to Finland */
+ lstrcpy(pszCountry,"FINLAND");
+ else if(!lstrcmpi(pszTwo,"ME"))
+ lstrcpy(pszCountry,"MONTENEGRO");
+ else if(!lstrcmpi(pszTwo,"RS") || !lstrcmpi(pszTwo,"CS"))
+ lstrcpy(pszCountry,"SERBIA");
+ /* convert */
+ for(i=0;i<nCountriesCount;i++) {
+ /* map different writings */
+ for(j=0;j<SIZEOF(differentCountryNames);j++)
+ if(!lstrcmpi(countries[i].szName,differentCountryNames[j].szMir)) {
+ buf=(char*)differentCountryNames[j].szCSV;
+ break;
+ }
+ if(j==SIZEOF(differentCountryNames))
+ buf=(char*)countries[i].szName;
+ /* check country */
+ if(!lstrcmpiA(pszCountry,buf)) {
+ dwOut=(DWORD)atoi(pszFrom);
+ AppendToByteBuffer(&buffer,(void*)&dwOut,sizeof(DWORD));
+ dwOut=(DWORD)atoi(pszTo);
+ AppendToByteBuffer(&buffer,(void*)&dwOut,sizeof(DWORD));
+ wOut=(WORD)countries[i].id;
+ AppendToByteBuffer(&buffer,(void*)&wOut,sizeof(WORD));
+ break;
+ }
+ }
+ /* not in list */
+ if(i==nCountriesCount) {
+ wsprintfA(out,"Unknown: %s-%s [%s, %s]\n",pszFrom,pszTo,pszTwo,pszCountry);
+ OutputDebugStringA(out); /* all ascii */
+ }
+ }
+ fclose(fp);
+ OutputDebugStringA("Done!\n"); /* all ascii */
+ if(buffer.buf!=NULL) {
+ HANDLE hFileOut;
+ DWORD cbWritten=0;
+ BYTE *compressed;
+ DWORD cbCompressed;
+ /* compress whole data */
+ OutputDebugStringA("Compressing...\n"); /* all ascii */
+ compressed=(BYTE*)mir_alloc(buffer.cbAlloced+384);
+ if(compressed!=NULL) {
+ cbCompressed=Huffman_Compress(buffer.buf,compressed,buffer.cbLength);
+ OutputDebugStringA("Done!\n"); /* all ascii */
+ OutputDebugStringA("Writing to file...\n"); /* all ascii */
+ hFileOut=CreateFile(pszFileOut,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
+ if(hFileOut!=INVALID_HANDLE_VALUE) {
+ /* store data length count at beginning */
+ dwOut=buffer.cbLength;
+ WriteFile(hFileOut,&dwOut,sizeof(DWORD),&cbWritten,NULL);
+ /* store compressed data records */
+ WriteFile(hFileOut,compressed,cbCompressed,&cbWritten,NULL);
+ CloseHandle(hFileOut);
+ }
+ OutputDebugStringA("Done!\n"); /* all ascii */
+ mir_free(compressed);
+ }
+ mir_free(buffer.buf);
+ }
+ return 0;
+ }
+ return 1;
+}
+
+static void BinConvThread(void *unused)
+{
+ UNREFERENCED_PARAMETER(unused);
+ /* debug version only */
+ if(MessageBox(NULL,_T("Looking for 'ip-to-country.csv' in current directory.\n"
+ "It will be converted into 'ip-to-country.bin'.\n"
+ "See debug output for more details.\n"
+ "This process may take very long."),_T("Bin Converter"),MB_OKCANCEL|MB_ICONINFORMATION|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL)==IDOK) {
+ EnumIpDataLines("ip-to-country.csv","ip-to-country.bin");
+ MessageBox(NULL,_T("Done!\n'ip-to-country.bin' has been created in current directory."),_T("Bin Converter"),MB_OK|MB_ICONINFORMATION|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ }
+}
+
+#endif // BINCONV
+
+/************************* Misc ***********************************/
+
+void InitIpToCountry(void)
+{
+ /* Record Cache */
+ InitializeCriticalSection(&csRecordCache);
+ nDataRecordsCount=0;
+ dataRecords=NULL;
+ /* Services */
+ hServiceIpToCountry=CreateServiceFunction(MS_FLAGS_IPTOCOUNTRY,ServiceIpToCountry);
+#ifdef BINCONV
+ mir_forkthread(BinConvThread,NULL);
+#endif
+}
+
+void UninitIpToCountry(void)
+{
+ /* Record Cache */
+ DeleteCriticalSection(&csRecordCache);
+ mir_free(dataRecords); /* does NULL check */
+ /* Servcies */
+ DestroyServiceFunction(hServiceIpToCountry);
+}
diff --git a/plugins/CountryFlags/main.c b/plugins/CountryFlags/main.c
new file mode 100644
index 0000000000..2da90447c2
--- /dev/null
+++ b/plugins/CountryFlags/main.c
@@ -0,0 +1,163 @@
+/*
+Miranda IM Country Flags Plugin
+Copyright (C) 2006-2007 H. Herkenrath
+
+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 (Flags-License.txt); if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "flags.h"
+#include "version.h"
+
+HINSTANCE hInst;
+PLUGINLINK *pluginLink;
+struct MM_INTERFACE mmi;
+int nCountriesCount;
+struct CountryListEntry *countries;
+
+static PLUGININFOEX pluginInfo={
+ sizeof(PLUGININFOEX),
+ "Country Flags",
+ PLUGIN_VERSION,
+#if defined(_DEBUG)
+ "Development build not intended for release. ("__DATE__")", /* autotranslated */
+#else
+ "Service offering misc country utilities as flag icons and a IP-to-Country database.", /* autotranslated */
+#endif
+ "H. Herkenrath",
+ PLUGIN_EMAIL, /* @ will be set later */
+ "© 2006-2007 H. Herkenrath",
+ PLUGIN_WEBSITE,
+ UNICODE_AWARE,
+ 0,
+#if defined(_UNICODE)
+ // {68C36842-3D95-4f4a-AB81-014D6593863B}
+ {0x68c36842,0x3d95,0x4f4a,{0xab,0x81,0x1,0x4d,0x65,0x93,0x86,0x3b}},
+#else
+ // {E0C4681C-E680-4262-8B44-7A9540C064FF}
+ {0xe0c4681c,0xe680,0x4262,{0x8b,0x44,0x7a,0x95,0x40,0xc0,0x64,0xff}}
+#endif
+};
+static const MUUID interfaces[]={MIID_FLAGS,MIID_LAST};
+
+BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,void *pReserved)
+{
+ UNREFERENCED_PARAMETER(pReserved);
+ if(fdwReason==DLL_PROCESS_ATTACH)
+ /* Do not call this function from a DLL that is linked to the static C run-time library (CRT).
+ * The static CRT requires DLL_THREAD_ATTACH and DLL_THREAD_DETATCH notifications to function properly. */
+ DisableThreadLibraryCalls(hInst=hinstDLL);
+ return TRUE;
+}
+
+static void InstallFile(const TCHAR *pszFileName,const TCHAR *pszDestSubDir)
+{
+ TCHAR szFileFrom[MAX_PATH+1],szFileTo[MAX_PATH+1],*p;
+ HANDLE hFile;
+
+ if(!GetModuleFileName(hInst,szFileFrom,SIZEOF(szFileFrom)-lstrlen(pszFileName)))
+ return;
+ p=_tcsrchr(szFileFrom,_T('\\'));
+ if(p!=NULL) *(++p)=0;
+ lstrcat(szFileFrom,pszFileName); /* buffer safe */
+
+ hFile=CreateFile(szFileFrom,0,FILE_SHARE_READ,0,OPEN_EXISTING,0,0);
+ if(hFile==INVALID_HANDLE_VALUE) return;
+ CloseHandle(hFile);
+
+ if(!GetModuleFileName(NULL,szFileTo,SIZEOF(szFileTo)-lstrlen(pszDestSubDir)-lstrlen(pszFileName)))
+ return;
+ p=_tcsrchr(szFileTo,_T('\\'));
+ if(p!=NULL) *(++p)=0;
+ lstrcat(szFileTo,pszDestSubDir); /* buffer safe */
+ CreateDirectory(szFileTo,NULL);
+ lstrcat(szFileTo,pszFileName); /* buffer safe */
+
+ if(!MoveFile(szFileFrom,szFileTo) && GetLastError()==ERROR_ALREADY_EXISTS) {
+ DeleteFile(szFileTo);
+ MoveFile(szFileFrom,szFileTo);
+ }
+}
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+__declspec(dllexport) const PLUGININFO* MirandaPluginInfo(DWORD mirandaVersion)
+{
+ if(mirandaVersion<PLUGIN_MAKE_VERSION(0,1,0,1)) return NULL;
+ pluginInfo.cbSize=sizeof(PLUGININFO); /* needed as v0.6 does equality check */
+ /* email obfuscated, made .rdata writable */
+ pluginInfo.authorEmail[PLUGIN_EMAIL_ATT_POS-1]='@';
+ return (PLUGININFO*)&pluginInfo; /* header is the same */
+}
+
+__declspec(dllexport) const PLUGININFOEX* MirandaPluginInfoEx(DWORD mirandaVersion)
+{
+ UNREFERENCED_PARAMETER(mirandaVersion);
+ pluginInfo.cbSize=sizeof(PLUGININFOEX);
+ /* email obfuscated, made .rdata writable */
+ pluginInfo.authorEmail[PLUGIN_EMAIL_ATT_POS-1]='@';
+ return &pluginInfo;
+}
+
+__declspec(dllexport) const MUUID* MirandaPluginInterfaces(void)
+{
+ return interfaces;
+}
+
+__declspec(dllexport) int Load(PLUGINLINK *link)
+{
+ pluginLink=link;
+
+ /* existance of MS_SYSTEM_GETVERSION and MS_LANGPACK_TRANSLATESTRING
+ * is checked in MirandaPluginInfo().
+ * Not placed in MirandaPluginInfo() to avoid MessageBoxes on plugin options.
+ * Using ANSI as LANG_UNICODE might not be supported. */
+ if(CallService(MS_SYSTEM_GETVERSION,0,0)<NEEDED_MIRANDA_VERSION) {
+ char szText[256];
+ mir_snprintf(szText,SIZEOF(szText),Translate("The Country Flags Plugin can not be loaded. It requires Miranda IM %hs or later."),NEEDED_MIRANDA_VERSION_STR);
+ MessageBoxA(NULL,szText,Translate("Country Flags Plugin"),MB_OK|MB_ICONINFORMATION|MB_SETFOREGROUND|MB_TOPMOST|MB_TASKMODAL);
+ return 1;
+ }
+ if(mir_getMMI(&mmi)) return 1;
+
+ PrepareBufferedFunctions();
+ InitCountryListExt();
+ if(CallService(MS_UTILS_GETCOUNTRYLIST,(WPARAM)&nCountriesCount,(LPARAM)&countries))
+ nCountriesCount=0;
+ InitIcons();
+ InitIpToCountry();
+ InitExtraImg();
+
+ /* installation */
+ InstallFile(_T("Flags-Readme.txt"),_T("Docs\\"));
+ InstallFile(_T("Flags-License.txt"),_T("Docs\\"));
+ InstallFile(_T("Flags-SDK.zip"),_T("Docs\\"));
+ return 0;
+}
+
+__declspec(dllexport) int Unload(void)
+{
+ KillBufferedFunctions();
+ UninitExtraImg();
+ UninitIpToCountry();
+ UninitIcons();
+ UninitCountryListExt();
+ return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/plugins/CountryFlags/res/flags.bmp b/plugins/CountryFlags/res/flags.bmp
new file mode 100644
index 0000000000..bfbf4a70e6
--- /dev/null
+++ b/plugins/CountryFlags/res/flags.bmp
Binary files differ
diff --git a/plugins/CountryFlags/res/ip-to-country.bin b/plugins/CountryFlags/res/ip-to-country.bin
new file mode 100644
index 0000000000..a43e8663e6
--- /dev/null
+++ b/plugins/CountryFlags/res/ip-to-country.bin
Binary files differ
diff --git a/plugins/CountryFlags/resource.h b/plugins/CountryFlags/resource.h
new file mode 100644
index 0000000000..a2cd0496d8
--- /dev/null
+++ b/plugins/CountryFlags/resource.h
@@ -0,0 +1,25 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by resource.rc
+//
+#define IDB_FLAGS 101
+#define IDR_IPTOCOUNTRY 102
+#define IDD_OPT_EXTRAIMG 103
+#define IDC_CHECK_SHOWSTATUSICONFLAG 1001
+#define IDC_CHECK_SHOWEXTRAIMGFLAG 1002
+#define IDC_TEXT_EXTRAIMGFLAGCOLUMN 1003
+#define IDC_COMBO_EXTRAIMGFLAGCOLUMN 1004
+#define IDC_CHECK_USEUNKNOWNFLAG 1005
+#define IDC_CHECK_USEIPTOCOUNTRY 1006
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NO_MFC 1
+#define _APS_NEXT_RESOURCE_VALUE 104
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1007
+#define _APS_NEXT_SYMED_VALUE 2001
+#endif
+#endif
diff --git a/plugins/CountryFlags/resource.rc b/plugins/CountryFlags/resource.rc
new file mode 100644
index 0000000000..eba35cb8e3
--- /dev/null
+++ b/plugins/CountryFlags/resource.rc
@@ -0,0 +1,128 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include <winres.h>
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Englisch (GB) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "#include <winres.h>\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE MOVEABLE PURE
+BEGIN
+ "#include ""version.rc""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Bitmap
+//
+
+IDB_FLAGS BITMAP DISCARDABLE "res/flags.bmp"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// BIN
+//
+
+IDR_IPTOCOUNTRY BIN DISCARDABLE "res/ip-to-country.bin"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_OPT_EXTRAIMG DIALOGEX 0, 0, 223, 93
+STYLE DS_FIXEDSYS | WS_CHILD
+EXSTYLE WS_EX_CONTROLPARENT
+FONT 8, "MS Shell Dlg"
+BEGIN
+ GROUPBOX "Country Flags",-1,3,0,220,93
+ CONTROL "Show country flag as &status icon on message window",
+ IDC_CHECK_SHOWSTATUSICONFLAG,"Button",BS_AUTOCHECKBOX |
+ WS_GROUP | WS_TABSTOP,12,14,206,10
+ CONTROL "Show country flag as &extra image on contact list",
+ IDC_CHECK_SHOWEXTRAIMGFLAG,"Button",BS_AUTOCHECKBOX |
+ WS_GROUP | WS_TABSTOP,12,27,206,10
+ LTEXT "In following contact list &column:",
+ IDC_TEXT_EXTRAIMGFLAGCOLUMN,24,42,110,8
+ COMBOBOX IDC_COMBO_EXTRAIMGFLAGCOLUMN,135,40,77,117,
+ CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
+ CONTROL "Use &unknown flag if the country can not be determined",
+ IDC_CHECK_USEUNKNOWNFLAG,"Button",BS_AUTOCHECKBOX |
+ WS_GROUP | WS_TABSTOP,12,77,206,10
+ CONTROL "Use &IP-to-country database for country detection",
+ IDC_CHECK_USEIPTOCOUNTRY,"Button",BS_AUTOCHECKBOX |
+ WS_GROUP | WS_TABSTOP,12,64,206,10
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO DISCARDABLE
+BEGIN
+ IDD_OPT_EXTRAIMG, DIALOG
+ BEGIN
+ VERTGUIDE, 3
+ VERTGUIDE, 12
+ VERTGUIDE, 24
+ VERTGUIDE, 218
+ HORZGUIDE, 42
+ HORZGUIDE, 52
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // Englisch (GB) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/plugins/CountryFlags/utils.c b/plugins/CountryFlags/utils.c
new file mode 100644
index 0000000000..d71b0acde3
--- /dev/null
+++ b/plugins/CountryFlags/utils.c
@@ -0,0 +1,162 @@
+/*
+Miranda IM Country Flags Plugin
+Copyright (C) 2006-1007 H. Herkenrath
+
+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 (Flags-License.txt); if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#include "flags.h"
+
+/************************* Buffered Functions *********************/
+
+struct BufferedCallData {
+ DWORD startTick;
+ UINT uElapse;
+ BUFFEREDPROC pfnBuffProc;
+ LPARAM lParam;
+ #ifdef _DEBUG
+ const char *pszProcName;
+ #endif
+};
+
+static UINT idBufferedTimer;
+static struct BufferedCallData *callList;
+static int nCallListCount;
+
+// always gets called in main message loop
+static void CALLBACK BufferedProcTimer(HWND hwnd,UINT msg,UINT idTimer,DWORD currentTick)
+{
+ int i;
+ struct BufferedCallData *buf;
+ UINT uElapsed,uElapseNext=USER_TIMER_MAXIMUM;
+ BUFFEREDPROC pfnBuffProc;
+ LPARAM lParam;
+ #ifdef _DEBUG
+ char szDbgLine[256];
+ const char *pszProcName;
+ #endif
+ UNREFERENCED_PARAMETER(msg);
+
+ for(i=0;i<nCallListCount;++i) {
+ /* find elapsed procs */
+ uElapsed=currentTick-callList[i].startTick; /* wraparound works */
+ if((uElapsed+USER_TIMER_MINIMUM)>=callList[i].uElapse) {
+ /* call elapsed proc */
+ pfnBuffProc=callList[i].pfnBuffProc;
+ lParam=callList[i].lParam;
+ #ifdef _DEBUG
+ pszProcName=callList[i].pszProcName;
+ #endif
+ /* resize storage array */
+ if((i+1)<nCallListCount)
+ MoveMemory(&callList[i],&callList[i+1],((nCallListCount-i-1)*sizeof(struct BufferedCallData)));
+ --nCallListCount;
+ --i; /* reiterate current */
+ if(nCallListCount) {
+ buf=(struct BufferedCallData*)mir_realloc(callList,nCallListCount*sizeof(struct BufferedCallData));
+ if(buf!=NULL) callList=buf;
+ } else {
+ mir_free(callList);
+ callList=NULL;
+ }
+ #ifdef _DEBUG
+ mir_snprintf(szDbgLine,sizeof(szDbgLine),"buffered call: %s(0x%X)\n",pszProcName,lParam); /* all ascii */
+ OutputDebugStringA(szDbgLine);
+ #endif
+ CallFunctionAsync((void (CALLBACK *)(void*))pfnBuffProc,(void*)lParam); /* compatible */
+ }
+ /* find next timer delay */
+ else if((callList[i].uElapse-uElapsed)<uElapseNext)
+ uElapseNext=callList[i].uElapse-uElapsed;
+ }
+
+ /* set next timer */
+ if(nCallListCount) {
+ #ifdef _DEBUG
+ mir_snprintf(szDbgLine,sizeof(szDbgLine),"next buffered timeout: %ums\n",uElapseNext); /* all ascii */
+ OutputDebugStringA(szDbgLine);
+ #endif
+ idBufferedTimer=SetTimer(hwnd,idBufferedTimer,uElapseNext,BufferedProcTimer); /* will be reset */
+ } else {
+ KillTimer(hwnd,idTimer);
+ idBufferedTimer=0;
+ #ifdef _DEBUG
+ OutputDebugStringA("empty buffered queue\n");
+ #endif
+ }
+}
+
+// assumes to be called in context of main thread
+#ifdef _DEBUG
+void _CallFunctionBuffered(BUFFEREDPROC pfnBuffProc,const char *pszProcName,LPARAM lParam,BOOL fAccumulateSameParam,UINT uElapse)
+#else
+void _CallFunctionBuffered(BUFFEREDPROC pfnBuffProc,LPARAM lParam,BOOL fAccumulateSameParam,UINT uElapse)
+#endif
+{
+ struct BufferedCallData *data=NULL;
+ int i;
+
+ /* find existing */
+ for(i=0;i<nCallListCount;++i)
+ if(callList[i].pfnBuffProc==pfnBuffProc)
+ if(!fAccumulateSameParam || callList[i].lParam==lParam) {
+ data=&callList[i];
+ break;
+ }
+ /* append new */
+ if(data==NULL) {
+ /* resize storage array */
+ data=(struct BufferedCallData*)mir_realloc(callList,(nCallListCount+1)*sizeof(struct BufferedCallData));
+ if(data==NULL) return;
+ callList=data;
+ data=&callList[nCallListCount];
+ ++nCallListCount;
+ }
+ /* set delay */
+ data->startTick=GetTickCount();
+ data->uElapse=uElapse;
+ data->lParam=lParam;
+ data->pfnBuffProc=pfnBuffProc;
+ #ifdef _DEBUG
+ { char szDbgLine[256];
+ data->pszProcName=pszProcName;
+ mir_snprintf(szDbgLine,sizeof(szDbgLine),"buffered queue: %s(0x%X)\n",pszProcName,lParam); /* all ascii */
+ OutputDebugStringA(szDbgLine);
+ if(!idBufferedTimer) {
+ mir_snprintf(szDbgLine,sizeof(szDbgLine),"next buffered timeout: %ums\n",uElapse); /* all ascii */
+ OutputDebugStringA(szDbgLine);
+ }
+ }
+ #endif
+ /* set next timer */
+ if(idBufferedTimer) uElapse=USER_TIMER_MINIMUM; /* will get recalculated */
+ idBufferedTimer=SetTimer(NULL,idBufferedTimer,uElapse,BufferedProcTimer);
+}
+
+// assumes to be called in context of main thread
+void PrepareBufferedFunctions(void)
+{
+ idBufferedTimer=0;
+ nCallListCount=0;
+ callList=NULL;
+}
+
+// assumes to be called in context of main thread
+void KillBufferedFunctions(void)
+{
+ if(idBufferedTimer) KillTimer(NULL,idBufferedTimer);
+ nCallListCount=0;
+ mir_free(callList); /* does NULL check */
+}
diff --git a/plugins/CountryFlags/version.h b/plugins/CountryFlags/version.h
new file mode 100644
index 0000000000..b1c58f55cc
--- /dev/null
+++ b/plugins/CountryFlags/version.h
@@ -0,0 +1,38 @@
+/*
+Miranda IM Country Flags Plugin
+Copyright (C) 2006-2007 H. Herkenrath
+
+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 (Flags-License.txt); if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+#define NEEDED_MIRANDA_VERSION PLUGIN_MAKE_VERSION(0,7,0,10)
+#define NEEDED_MIRANDA_VERSION_STR "0.7 alpha build #10"
+#define PLUGIN_VERSION PLUGIN_MAKE_VERSION(0,1,0,3)
+#define FILE_VERSION 0,1,0,3
+
+#ifdef _DEBUG
+ #define FILE_VERSION_STR "0.1.0.4 alpha"
+#else
+ #define FILE_VERSION_STR "0.1.0.3"
+#endif
+
+#define PLUGIN_EMAIL "hrathh users.sourceforge.net"
+#define PLUGIN_EMAIL_ATT_POS 7 /* position of the @-sign in the email adress above */
+
+#ifdef _UNICODE
+ #define PLUGIN_WEBSITE "http://addons.miranda-im.org/details.php?action=viewfile&id=3463"
+#else
+ #define PLUGIN_WEBSITE "http://addons.miranda-im.org/details.php?action=viewfile&id=3462"
+#endif
diff --git a/plugins/CountryFlags/version.rc b/plugins/CountryFlags/version.rc
new file mode 100644
index 0000000000..8694503dee
--- /dev/null
+++ b/plugins/CountryFlags/version.rc
@@ -0,0 +1,47 @@
+#ifndef _MAC
+
+#include <version.h>
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION FILE_VERSION
+ PRODUCTVERSION FILE_VERSION
+ FILEFLAGSMASK 0x0L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x40004L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "000004b0"
+ BEGIN
+ VALUE "Comments", "Licensed under the terms of the GNU General Public License"
+ VALUE "FileDescription", "Country Flags Plugin for Miranda IM"
+ VALUE "FileVersion", FILE_VERSION_STR
+ VALUE "InternalName", "CountryUtils"
+ VALUE "LegalCopyright", "Copyright © 2006-2007 H. Herkenrath"
+ VALUE "OriginalFilename", "flags.dll"
+ VALUE "ProductName", "Country Flags"
+ VALUE "ProductVersion", FILE_VERSION_STR
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0, 1200
+ END
+END
+
+#endif // !_MAC
+
+
+
+