From d5d68cf53f2b4e7607ffe042a45b5aeea0a47d1c Mon Sep 17 00:00:00 2001 From: Ged Murphy Date: Sat, 12 May 2007 10:14:45 +0000 Subject: [PATCH] - Add winhelp based on Wine. - Not fully complete and has some bugs. - go to help -> help on help for a preview svn path=/trunk/; revision=26719 --- reactos/base/applications/applications.rbuild | 3 + reactos/base/applications/winhelp/Bg.rc | 69 + reactos/base/applications/winhelp/Cs.rc | 74 + reactos/base/applications/winhelp/Da.rc | 72 + reactos/base/applications/winhelp/De.rc | 71 + reactos/base/applications/winhelp/En.rc | 70 + reactos/base/applications/winhelp/Eo.rc | 72 + reactos/base/applications/winhelp/Es.rc | 71 + reactos/base/applications/winhelp/Fi.rc | 72 + reactos/base/applications/winhelp/Fr.rc | 72 + reactos/base/applications/winhelp/Hu.rc | 72 + reactos/base/applications/winhelp/It.rc | 71 + reactos/base/applications/winhelp/Ko.rc | 71 + reactos/base/applications/winhelp/Nl.rc | 69 + reactos/base/applications/winhelp/No.rc | 69 + reactos/base/applications/winhelp/Pl.rc | 71 + reactos/base/applications/winhelp/Pt.rc | 130 ++ reactos/base/applications/winhelp/Ru.rc | 69 + reactos/base/applications/winhelp/Si.rc | 69 + reactos/base/applications/winhelp/Sk.rc | 66 + reactos/base/applications/winhelp/Sw.rc | 72 + reactos/base/applications/winhelp/Tr.rc | 69 + reactos/base/applications/winhelp/Va.rc | 76 + reactos/base/applications/winhelp/Wa.rc | 76 + reactos/base/applications/winhelp/Zh.rc | 70 + reactos/base/applications/winhelp/callback.c | 180 ++ reactos/base/applications/winhelp/hlpfile.c | 2065 +++++++++++++++++ reactos/base/applications/winhelp/hlpfile.h | 163 ++ reactos/base/applications/winhelp/lex.yy.c | 1841 +++++++++++++++ reactos/base/applications/winhelp/macro.c | 928 ++++++++ reactos/base/applications/winhelp/macro.h | 140 ++ reactos/base/applications/winhelp/macro.lex.l | 295 +++ reactos/base/applications/winhelp/rsrc.rc | 48 + reactos/base/applications/winhelp/string.c | 35 + reactos/base/applications/winhelp/winhelp.c | 1930 +++++++++++++++ reactos/base/applications/winhelp/winhelp.h | 200 ++ .../base/applications/winhelp/winhelp.rbuild | 26 + .../base/applications/winhelp/winhelp_res.h | 32 + 38 files changed, 9649 insertions(+) create mode 100644 reactos/base/applications/winhelp/Bg.rc create mode 100644 reactos/base/applications/winhelp/Cs.rc create mode 100644 reactos/base/applications/winhelp/Da.rc create mode 100644 reactos/base/applications/winhelp/De.rc create mode 100644 reactos/base/applications/winhelp/En.rc create mode 100644 reactos/base/applications/winhelp/Eo.rc create mode 100644 reactos/base/applications/winhelp/Es.rc create mode 100644 reactos/base/applications/winhelp/Fi.rc create mode 100644 reactos/base/applications/winhelp/Fr.rc create mode 100644 reactos/base/applications/winhelp/Hu.rc create mode 100644 reactos/base/applications/winhelp/It.rc create mode 100644 reactos/base/applications/winhelp/Ko.rc create mode 100644 reactos/base/applications/winhelp/Nl.rc create mode 100644 reactos/base/applications/winhelp/No.rc create mode 100644 reactos/base/applications/winhelp/Pl.rc create mode 100644 reactos/base/applications/winhelp/Pt.rc create mode 100644 reactos/base/applications/winhelp/Ru.rc create mode 100644 reactos/base/applications/winhelp/Si.rc create mode 100644 reactos/base/applications/winhelp/Sk.rc create mode 100644 reactos/base/applications/winhelp/Sw.rc create mode 100644 reactos/base/applications/winhelp/Tr.rc create mode 100644 reactos/base/applications/winhelp/Va.rc create mode 100644 reactos/base/applications/winhelp/Wa.rc create mode 100644 reactos/base/applications/winhelp/Zh.rc create mode 100644 reactos/base/applications/winhelp/callback.c create mode 100644 reactos/base/applications/winhelp/hlpfile.c create mode 100644 reactos/base/applications/winhelp/hlpfile.h create mode 100644 reactos/base/applications/winhelp/lex.yy.c create mode 100644 reactos/base/applications/winhelp/macro.c create mode 100644 reactos/base/applications/winhelp/macro.h create mode 100644 reactos/base/applications/winhelp/macro.lex.l create mode 100644 reactos/base/applications/winhelp/rsrc.rc create mode 100644 reactos/base/applications/winhelp/string.c create mode 100644 reactos/base/applications/winhelp/winhelp.c create mode 100644 reactos/base/applications/winhelp/winhelp.h create mode 100644 reactos/base/applications/winhelp/winhelp.rbuild create mode 100644 reactos/base/applications/winhelp/winhelp_res.h diff --git a/reactos/base/applications/applications.rbuild b/reactos/base/applications/applications.rbuild index 339db4b3990..ca1fe852e3c 100644 --- a/reactos/base/applications/applications.rbuild +++ b/reactos/base/applications/applications.rbuild @@ -55,6 +55,9 @@ + + + diff --git a/reactos/base/applications/winhelp/Bg.rc b/reactos/base/applications/winhelp/Bg.rc new file mode 100644 index 00000000000..d04a9d077da --- /dev/null +++ b/reactos/base/applications/winhelp/Bg.rc @@ -0,0 +1,69 @@ +/* + * Help Viewer Bulgarian resource + * + * Copyright 2005 Milko Krachounov + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT +{ + POPUP "&" { + MENUITEM "&", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&", MNID_FILE_PRINT + MENUITEM "& ...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&", MNID_FILE_EXIT + } + POPUP "&" { + MENUITEM "&...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&...", MNID_EDIT_ANNOTATE + } + POPUP "&" { + MENUITEM "&...", MNID_BKMK_DEFINE + } + POPUP "&" { + MENUITEM " & ", MNID_HELP_HELPON + MENUITEM " &", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "& WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ +STRINGTABLE DISCARDABLE LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT +{ +STID_WINE_HELP, "WINE " +STID_WHERROR, "" +STID_WARNING, "" +STID_INFO, "" +STID_NOT_IMPLEMENTED, " " +STID_HLPFILE_ERROR_s, " `%s'" +STID_CONTENTS, "&" +STID_SEARCH, "&" +STID_BACK, "&" +STID_HISTORY, "&" +STID_TOPICS, "&" +STID_ALL_FILES, " (*.*)" +STID_HELP_FILES_HLP, " (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Cs.rc b/reactos/base/applications/winhelp/Cs.rc new file mode 100644 index 00000000000..06c2e17517c --- /dev/null +++ b/reactos/base/applications/winhelp/Cs.rc @@ -0,0 +1,74 @@ +/* Hey, Emacs, open this file with -*- coding: cp1250 -*- + * + * Help Viewer Czech resources + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Sylvain Petreolle + * Copyright 2004 David Kredba + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Czech strings in CP1250 */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +{ + POPUP "&Soubor" { + MENUITEM "&Otevt", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&Tisk", MNID_FILE_PRINT + MENUITEM "Na&staven tisku...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&Konec", MNID_FILE_EXIT + } + POPUP "prav&y" { + MENUITEM "&Koprovat...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "P&oznamenat si...", MNID_EDIT_ANNOTATE + } + POPUP "&Zloka" { + MENUITEM "Pi&dat...", MNID_BKMK_DEFINE + } + POPUP "&Npovda" { + MENUITEM "Np&ovda k npovd", MNID_HELP_HELPON + MENUITEM "Vdy na &vrchu", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Informace...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "O &WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ +STRINGTABLE DISCARDABLE LANGUAGE LANG_CZECH, SUBLANG_DEFAULT +{ +STID_WINE_HELP, "Npovda WINE" +STID_WHERROR, "CHYBA" +STID_WARNING, "VAROVN" +STID_INFO, "Informace" +STID_NOT_IMPLEMENTED, "Nen implementovno" +STID_HLPFILE_ERROR_s, "Nelze pest soubor npovdy `%s'" +STID_CONTENTS, "&Obsah" +STID_SEARCH, "&Hledat" +STID_BACK, "&Zpt" +STID_HISTORY, "&Historie" +STID_TOPICS, "&Tmata" +STID_ALL_FILES, "Vechny soubory (*.*)" +STID_HELP_FILES_HLP, "Soubory npovdy (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Da.rc b/reactos/base/applications/winhelp/Da.rc new file mode 100644 index 00000000000..522cdae99a3 --- /dev/null +++ b/reactos/base/applications/winhelp/Da.rc @@ -0,0 +1,72 @@ +/* + * Help Viewer + * + * Copyright 1997 Henrik Olsen + * Copyright 2002 Sylvain Petreolle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_DANISH, SUBLANG_DEFAULT +{ + POPUP "&Filer" { + MENUITEM "&bn...", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&Udskriv emne", MNID_FILE_PRINT + MENUITEM "&Indstil printer", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&Afslut", MNID_FILE_EXIT + } + POPUP "&Rediger" { + MENUITEM "K&opier...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Anmrk...", MNID_EDIT_ANNOTATE + } + POPUP "Bog&mrke" { + MENUITEM "&Definer...", MNID_BKMK_DEFINE + } + POPUP "&Hjlp" { + MENUITEM "&Brug af Hjlp", MNID_HELP_HELPON + MENUITEM "Altid &verst", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Info...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "Om &WINE", MNID_HELP_WINE +#endif + } +} + + +/* Strings */ + +STRINGTABLE DISCARDABLE LANGUAGE LANG_DANISH, SUBLANG_DEFAULT +{ +STID_WINE_HELP, "WINE Hjlp" +STID_WHERROR, "FEJL" +STID_WARNING, "ADVARSEL" +STID_INFO, "Information" +STID_NOT_IMPLEMENTED, "Ikke implementeret" +STID_HLPFILE_ERROR_s, "Fejl ved indlsning af filen `%s'" +STID_CONTENTS, "&Indhold" +STID_SEARCH, "&Sg" +STID_BACK, "&Tilbage" +STID_HISTORY, "&Oversigt" +STID_TOPICS, "To&pics" +STID_ALL_FILES, "Alle filer (*.*)" +STID_HELP_FILES_HLP, "Hjlpe filer (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/De.rc b/reactos/base/applications/winhelp/De.rc new file mode 100644 index 00000000000..8ec84cd4fb9 --- /dev/null +++ b/reactos/base/applications/winhelp/De.rc @@ -0,0 +1,71 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Sylvain Petreolle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL +{ + POPUP "&Datei" { + MENUITEM "&ffnen...", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "Thema &drucken", MNID_FILE_PRINT + MENUITEM "Drucker&einrichtung...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&Beenden", MNID_FILE_EXIT + } + POPUP "&Bearbeiten" { + MENUITEM "&Kopieren...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Anmerken...", MNID_EDIT_ANNOTATE + } + POPUP "&Lesezeichen" { + MENUITEM "&Definieren...", MNID_BKMK_DEFINE + } + POPUP "&Hilfe" { + MENUITEM "&Hilfe benutzen", MNID_HELP_HELPON + MENUITEM "Immer im &Vordergrund", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Info...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "&ber WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ + +STRINGTABLE DISCARDABLE LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL +{ +STID_WINE_HELP, "WINE Hilfe" +STID_WHERROR, "FEHLER" +STID_WARNING, "ACHTUNG" +STID_INFO, "Information" +STID_NOT_IMPLEMENTED, "Nicht implementiert" +STID_HLPFILE_ERROR_s, "Fehler beim Lesen der Hilfe-Datei `%s'" +STID_CONTENTS, "&Inhalt" +STID_SEARCH, "&Suchen" +STID_BACK, "&Zurck" +STID_HISTORY, "&Bisher" +STID_TOPICS, "&Topics" +STID_ALL_FILES, "Alle Dateien (*.*)" +STID_HELP_FILES_HLP, "Hilfe-Dateien (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/En.rc b/reactos/base/applications/winhelp/En.rc new file mode 100644 index 00000000000..8c4bac293a6 --- /dev/null +++ b/reactos/base/applications/winhelp/En.rc @@ -0,0 +1,70 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Sylvain Petreolle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT +{ + POPUP "&File" { + MENUITEM "&Open", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&Print", MNID_FILE_PRINT + MENUITEM "Printer &setup...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "E&xit", MNID_FILE_EXIT + } + POPUP "&Edit" { + MENUITEM "&Copy...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Annotate...", MNID_EDIT_ANNOTATE + } + POPUP "&Bookmark" { + MENUITEM "&Define...", MNID_BKMK_DEFINE + } + POPUP "&Help" { + MENUITEM "Help &on help", MNID_HELP_HELPON + MENUITEM "Always on &top", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Info...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "&About WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ +STRINGTABLE DISCARDABLE LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT +{ +STID_WINE_HELP, "WINE Help" +STID_WHERROR, "ERROR" +STID_WARNING, "WARNING" +STID_INFO, "Information" +STID_NOT_IMPLEMENTED, "Not implemented" +STID_HLPFILE_ERROR_s, "Error while reading the help file `%s'" +STID_CONTENTS, "&Contents" +STID_SEARCH, "&Search" +STID_BACK, "&Back" +STID_HISTORY, "&History" +STID_TOPICS, "&Topics" +STID_ALL_FILES, "All files (*.*)" +STID_HELP_FILES_HLP, "Help files (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Eo.rc b/reactos/base/applications/winhelp/Eo.rc new file mode 100644 index 00000000000..cc8ef666e46 --- /dev/null +++ b/reactos/base/applications/winhelp/Eo.rc @@ -0,0 +1,72 @@ +/* + * Help Viewer + * Esperanto Language Support + * + * Copyright 2006 Antonio Codazzi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Cxapelitaj literoj estas en Latin-3 iso8859-3 */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT +{ + POPUP "&Dosiero" { + MENUITEM "&Malfermu", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&Presu", MNID_FILE_PRINT + MENUITEM "&Impozu Printilon...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&Finu", MNID_FILE_EXIT + } + POPUP "&Redakto" { + MENUITEM "&Kopiu...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Notu...", MNID_EDIT_ANNOTATE + } + POPUP "&Legosigno" { + MENUITEM "&Difinu...", MNID_BKMK_DEFINE + } + POPUP "&Helpo" { + MENUITEM "&Helpu pri helpo", MNID_HELP_HELPON + MENUITEM "iam &supre", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Pri...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "&Pri WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ +STRINGTABLE DISCARDABLE LANGUAGE LANG_ESPERANTO, SUBLANG_DEFAULT +{ +STID_WINE_HELP, "WINE Helpanto" +STID_WHERROR, "ERARO" +STID_WARNING, "ATENTU" +STID_INFO, "Informo pri" +STID_NOT_IMPLEMENTED, "Ne-implementata" +STID_HLPFILE_ERROR_s, "Eraro dum la legado de helpdosiero `%s'" +STID_CONTENTS, "&Enhavo" +STID_SEARCH, "&Seru" +STID_BACK, "&Retro" +STID_HISTORY, "Krono&logio" +STID_TOPICS, "&Temoj" +STID_ALL_FILES, "Tutaj dosieroj (*.*)" +STID_HELP_FILES_HLP, "Helpaj dosieroj (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Es.rc b/reactos/base/applications/winhelp/Es.rc new file mode 100644 index 00000000000..93d9223bd39 --- /dev/null +++ b/reactos/base/applications/winhelp/Es.rc @@ -0,0 +1,71 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Sylvain Petreolle + * Copyright 2003, 2004 Jos Manuel Ferrer Ortiz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL +{ + POPUP "&Archivo" { + MENUITEM "A&brir...", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&Imprimir", MNID_FILE_PRINT + MENUITEM "&Configuracin impresora...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&Salir", MNID_FILE_EXIT + } + POPUP "&Editar" { + MENUITEM "&Copiar...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Anotar...", MNID_EDIT_ANNOTATE + } + POPUP "&Marcador" { + MENUITEM "&Definir...", MNID_BKMK_DEFINE + } + POPUP "A&yuda" { + MENUITEM "&Ayuda sobre la ayuda", MNID_HELP_HELPON + MENUITEM "&Siempre visible", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Info...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "&Acerca de WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ +STRINGTABLE DISCARDABLE LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL +{ +STID_WINE_HELP, "Ayuda de WINE" +STID_WHERROR, "ERROR" +STID_WARNING, "ADVERTENCIA" +STID_INFO, "Informacin" +STID_NOT_IMPLEMENTED, "An no implementado" +STID_HLPFILE_ERROR_s, "Error al leer el archivo de ayuda `%s'" +STID_CONTENTS, "&ndice" +STID_SEARCH, "&Buscar" +STID_BACK, "&Anterior" +STID_HISTORY, "&Historial" +STID_TOPICS, "&Temas" +STID_ALL_FILES, "Todos los archivos (*.*)" +STID_HELP_FILES_HLP, "Archivos de ayuda (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Fi.rc b/reactos/base/applications/winhelp/Fi.rc new file mode 100644 index 00000000000..90de636d2be --- /dev/null +++ b/reactos/base/applications/winhelp/Fi.rc @@ -0,0 +1,72 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Finnish language by Jussi Tirkkonen + * Copyright 2002 Sylvain Petreolle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT +{ + POPUP "&Tiedosto" { + MENUITEM "&Avaa...", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&Tulosta", MNID_FILE_PRINT + MENUITEM "&Kirjoittimen asetukset...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&Lopeta", MNID_FILE_EXIT + } + POPUP "&Muokkaa" { + MENUITEM "&Kopioi...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Huomautus...", MNID_EDIT_ANNOTATE + } + POPUP "&Kirjanmerkki" { + MENUITEM "&Aseta...", MNID_BKMK_DEFINE + } + POPUP "&Ohje" { + MENUITEM "&Ohjeen kytt", MNID_HELP_HELPON + MENUITEM "&Aina pllimmisen", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "T&ietoja...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "&Tietoja WINEst", MNID_HELP_WINE +#endif + } +} + +/* Strings */ + +STRINGTABLE DISCARDABLE LANGUAGE LANG_FINNISH, SUBLANG_DEFAULT +{ +STID_WINE_HELP, "WINE Ohje" +STID_WHERROR, "VIRHE" +STID_WARNING, "VAROITUS" +STID_INFO, "Tietoja" +STID_NOT_IMPLEMENTED, "Ei kytettviss" +STID_HLPFILE_ERROR_s, "Virhe luettaessa ohjetiedostoa `%s'" +STID_CONTENTS, "&Sisllys" +STID_SEARCH, "&Etsi" +STID_BACK, "&Takaisin" +STID_HISTORY, "&Luetut" +STID_TOPICS, "T&opics" +STID_ALL_FILES, "Kaikki tiedostot (*.*)" +STID_HELP_FILES_HLP, "Ohjetiedostot (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Fr.rc b/reactos/base/applications/winhelp/Fr.rc new file mode 100644 index 00000000000..73185071395 --- /dev/null +++ b/reactos/base/applications/winhelp/Fr.rc @@ -0,0 +1,72 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Sylvain Petreolle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL + +MAIN_MENU MENU +{ + POPUP "&Fichier" { + MENUITEM "&Ouvrir", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "Im&primer", MNID_FILE_PRINT + MENUITEM "&Configuration de l'imprimante...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&Quitter", MNID_FILE_EXIT + } + POPUP "&dition" { + MENUITEM "&Copier...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Annotation...", MNID_EDIT_ANNOTATE + } + POPUP "&Signet" { + MENUITEM "&Dfinir...", MNID_BKMK_DEFINE + } + POPUP "Aid&e" { + MENUITEM "&Utiliser l'aide", MNID_HELP_HELPON + MENUITEM "&Toujours visible", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Info...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM " &propos de WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ +STRINGTABLE DISCARDABLE +{ +STID_WINE_HELP, "Aide de WINE" +STID_WHERROR, "ERREUR" +STID_WARNING, "ATTENTION" +STID_INFO, "Information" +STID_NOT_IMPLEMENTED, "Non implment" +STID_HLPFILE_ERROR_s, "Une erreur est survenue en lisant le fichier d'aide %s" +STID_CONTENTS, "&Index" +STID_SEARCH, "&Rechercher" +STID_BACK, "&Prcdent" +STID_HISTORY, "&Historique" +STID_TOPICS, "&Sujets" +STID_ALL_FILES, "Tous fichiers (*.*)" +STID_HELP_FILES_HLP, "Fichiers d'aide (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Hu.rc b/reactos/base/applications/winhelp/Hu.rc new file mode 100644 index 00000000000..8f4ef53b073 --- /dev/null +++ b/reactos/base/applications/winhelp/Hu.rc @@ -0,0 +1,72 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Sylvain Petreolle + * Copyright 2002 Zoly Nagy + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT +{ + POPUP "&Fjl" { + MENUITEM "&Megnyits...", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&Nyomtats", MNID_FILE_PRINT + MENUITEM "Nyomtat &bellts...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&Kilps", MNID_FILE_EXIT + } + POPUP "&Szerkeszts" { + MENUITEM "&Msols...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Jegyzet...", MNID_EDIT_ANNOTATE + } + POPUP "&Knyvjelz" { + MENUITEM "&Definils...", MNID_BKMK_DEFINE + } + POPUP "&Sg" { + MENUITEM "&Hasznlat", MNID_HELP_HELPON + MENUITEM "Mindig &legfell", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Informci...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "&&A WINE-rl", MNID_HELP_WINE +#endif + } +} + +/* Strings */ + +STRINGTABLE DISCARDABLE LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT +{ +STID_WINE_HELP, "WINE sg" +STID_WHERROR, "HIBA" +STID_WARNING, "FIGYELMEZTETS" +STID_INFO, "Informci" +STID_NOT_IMPLEMENTED, "Nincs implementlva" +STID_HLPFILE_ERROR_s, "Hiba a `%s' file olvassakor" +STID_CONTENTS, "&Tartalom" +STID_SEARCH, "&Keress" +STID_BACK, "&Vissza" +STID_HISTORY, "&Elzmny" +STID_TOPICS, "&Tmakrk" +STID_ALL_FILES, "Minden fjl (*.*)" +STID_HELP_FILES_HLP, "Sg fjlok (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/It.rc b/reactos/base/applications/winhelp/It.rc new file mode 100644 index 00000000000..bce3f14ab60 --- /dev/null +++ b/reactos/base/applications/winhelp/It.rc @@ -0,0 +1,71 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Sylvain Petreolle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL +{ + POPUP "&File" { + MENUITEM "&Apri...", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "S&tampa", MNID_FILE_PRINT + MENUITEM "&Setup stampante...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&Esci", MNID_FILE_EXIT + } + POPUP "&Modifica" { + MENUITEM "&Copia...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Annota...", MNID_EDIT_ANNOTATE + } + POPUP "&Segnalibro" { + MENUITEM "&Definisci...", MNID_BKMK_DEFINE + } + POPUP "&?" { + MENUITEM "&Aiuto sulla guida", MNID_HELP_HELPON + MENUITEM "Sempre in primo &piano", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Informazioni su...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "&Informazion su WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ + +STRINGTABLE DISCARDABLE LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL +{ +STID_WINE_HELP, "Guida di WINE" +STID_WHERROR, "ERRORE" +STID_WARNING, "ATTENZIONE" +STID_INFO, "Informazione" +STID_NOT_IMPLEMENTED, "Non ancora implementato" +STID_HLPFILE_ERROR_s, "Errore di lettura del file della Guida `%s'" +STID_CONTENTS, "&Sommario" +STID_SEARCH, "&Trova" +STID_BACK, "&Precedente" +STID_HISTORY, "&Cronologia" +STID_TOPICS, "&Argomenti" +STID_ALL_FILES, "Tutti i file (*.*)" +STID_HELP_FILES_HLP, "File della Guida (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Ko.rc b/reactos/base/applications/winhelp/Ko.rc new file mode 100644 index 00000000000..4db5070f056 --- /dev/null +++ b/reactos/base/applications/winhelp/Ko.rc @@ -0,0 +1,71 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Sylvain Petreolle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_KOREAN, SUBLANG_NEUTRAL +{ + POPUP "(&F)" { + MENUITEM "(&O)...", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "μ(&P)", MNID_FILE_PRINT + MENUITEM " (&S)...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "(&E)", MNID_FILE_EXIT + } + POPUP "(&E)" { + MENUITEM "(&C)...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "ּ(&A)...", MNID_EDIT_ANNOTATE + } + POPUP "å(&B)" { + MENUITEM "(&D)...", MNID_BKMK_DEFINE + } + POPUP "(&H)" { + MENUITEM " (&O)", MNID_HELP_HELPON + MENUITEM "׻ (&T)", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "(&I)...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "Wine Ͽ(&A)", MNID_HELP_WINE +#endif + } +} + +/* Strings */ + +STRINGTABLE DISCARDABLE LANGUAGE LANG_KOREAN, SUBLANG_NEUTRAL +{ +STID_WINE_HELP, "Wine " +STID_WHERROR, "" +STID_WARNING, "" +STID_INFO, "" +STID_NOT_IMPLEMENTED, " ʾ" +STID_HLPFILE_ERROR_s, " `%s' д ߻" +STID_CONTENTS, "(&C)" +STID_SEARCH, "ã(&S)" +STID_BACK, "ڷ(&B)" +STID_HISTORY, "丮(&H)" +STID_TOPICS, "(&T)" +STID_ALL_FILES, " (*.*)" +STID_HELP_FILES_HLP, " (*.hlp)" +STID_FILE_NOT_FOUND_s "%s ã ϴ'. ãڽϱ?" +} diff --git a/reactos/base/applications/winhelp/Nl.rc b/reactos/base/applications/winhelp/Nl.rc new file mode 100644 index 00000000000..44ecd902683 --- /dev/null +++ b/reactos/base/applications/winhelp/Nl.rc @@ -0,0 +1,69 @@ +/* + * Help Viewer (Dutch resources) + * + * Copyright 2003 Hans Leidekker + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL +{ + POPUP "&Bestand" { + MENUITEM "&Openen", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "Af&drukken", MNID_FILE_PRINT + MENUITEM "&Printerinstellingen...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&Afsluiten", MNID_FILE_EXIT + } + POPUP "&Bewerken" { + MENUITEM "&Kopiren...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Annoteren...", MNID_EDIT_ANNOTATE + } + POPUP "&Favorieten" { + MENUITEM "&Aanmaken...", MNID_BKMK_DEFINE + } + POPUP "&Help" { + MENUITEM "Hulp &bij help", MNID_HELP_HELPON + MENUITEM "Altijd &zichtbaar", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Info...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "&Over WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ +STRINGTABLE DISCARDABLE LANGUAGE LANG_DUTCH, SUBLANG_NEUTRAL +{ +STID_WINE_HELP, "WINE Help" +STID_WHERROR, "FOUT" +STID_WARNING, "WAARSCHUWING" +STID_INFO, "Informatie" +STID_NOT_IMPLEMENTED, "Niet gemplementeerd" +STID_HLPFILE_ERROR_s, "Fout bij het lezen van het helpbestand `%s'" +STID_CONTENTS, "&Inhoud" +STID_SEARCH, "&Zoeken" +STID_BACK, "&Terug" +STID_HISTORY, "&Geschiedenis" +STID_TOPICS, "&Onderwerpen" +STID_ALL_FILES, "Alle bestanden (*.*)" +STID_HELP_FILES_HLP, "Helpbestanden (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/No.rc b/reactos/base/applications/winhelp/No.rc new file mode 100644 index 00000000000..f016efb5792 --- /dev/null +++ b/reactos/base/applications/winhelp/No.rc @@ -0,0 +1,69 @@ +/* + * Help Viewer + * + * Copyright 2005 Alexander N. Srnes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL +{ + POPUP "&Fil" { + MENUITEM "&pne", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "Skriv &ut", MNID_FILE_PRINT + MENUITEM "Opp&sett av skriveren . . .", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&Avslutt", MNID_FILE_EXIT + } + POPUP "R&ediger" { + MENUITEM "&Kopier . . .", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "K&ommenter . . .", MNID_EDIT_ANNOTATE + } + POPUP "&Bokmerke" { + MENUITEM "&Definer . . .", MNID_BKMK_DEFINE + } + POPUP "&Hjelp" { + MENUITEM "&Hjelp til Hjelp", MNID_HELP_HELPON + MENUITEM "All&tid verst", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Informasjon . . .", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "&om WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ +STRINGTABLE DISCARDABLE LANGUAGE LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL +{ +STID_WINE_HELP, "Hjelp" +STID_WHERROR, "FEIL" +STID_WARNING, "ADVARSEL" +STID_INFO, "Informasjon" +STID_NOT_IMPLEMENTED, "Ikke implementert" +STID_HLPFILE_ERROR_s, "Feil ved lesing av hjelpefilen '%s'" +STID_CONTENTS, "&Innhold" +STID_SEARCH, "&Sk" +STID_BACK, "Til&bake" +STID_HISTORY, "&Historikk" +STID_TOPICS, "&Emner" +STID_ALL_FILES, "Alle filer (*.*)" +STID_HELP_FILES_HLP, "Hjelp-filer (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Pl.rc b/reactos/base/applications/winhelp/Pl.rc new file mode 100644 index 00000000000..1c90a0ce43f --- /dev/null +++ b/reactos/base/applications/winhelp/Pl.rc @@ -0,0 +1,71 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Sylvain Petreolle + * Copyright 2004 Piotr Caban + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_POLISH, SUBLANG_DEFAULT +{ + POPUP "&Plik" { + MENUITEM "&Otwrz", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&Drukuj", MNID_FILE_PRINT + MENUITEM "&Ustawienia drukarki...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&Wyjcie", MNID_FILE_EXIT + } + POPUP "&Edycja" { + MENUITEM "&Kopiuj...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Skomentuj...", MNID_EDIT_ANNOTATE + } + POPUP "&Zakadka" { + MENUITEM "&Zdefiniuj...", MNID_BKMK_DEFINE + } + POPUP "Pomo&c" { + MENUITEM "&Pomoc", MNID_HELP_HELPON + MENUITEM "&Zawsze na wierzchu", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&O programie...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "&O programie WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ +STRINGTABLE DISCARDABLE LANGUAGE LANG_POLISH, SUBLANG_DEFAULT +{ +STID_WINE_HELP, "WINE - Pomoc" +STID_WHERROR, "BD" +STID_WARNING, "OSTRZEENIE" +STID_INFO, "Informacja" +STID_NOT_IMPLEMENTED, "Nie zaimplementowane" +STID_HLPFILE_ERROR_s, "Bd w trakcie odczytu pliku pomocy `%s'" +STID_CONTENTS, "&Zawarto" +STID_SEARCH, "&Szukaj" +STID_BACK, "&Wstecz" +STID_HISTORY, "&Historia" +STID_TOPICS, "&Tematy" +STID_ALL_FILES, "Wszystkie pliki (*.*)" +STID_HELP_FILES_HLP, "Pliki pomocy (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Pt.rc b/reactos/base/applications/winhelp/Pt.rc new file mode 100644 index 00000000000..d080c1929f1 --- /dev/null +++ b/reactos/base/applications/winhelp/Pt.rc @@ -0,0 +1,130 @@ +/* + * Help Viewer + * Portuguese Language Support + * + * Copyright 1996 Ulrich Schmid + * Portuguese translation by Gustavo Junior Alves + * Copyright 2002 Sylvain Petreolle + * Copyright 2003 Marcelo Duarte + * Copyright 2004 Amrico Jos Melo + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN + +MAIN_MENU MENU +{ + POPUP "&Arquivo" { + MENUITEM "&Abrir...", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&Imprimir", MNID_FILE_PRINT + MENUITEM "&Configurar Impressora...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "Sai&r", MNID_FILE_EXIT + } + POPUP "&Editar" { + MENUITEM "&Copiar...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Anotar...", MNID_EDIT_ANNOTATE + } + POPUP "In&dicador" { + MENUITEM "&Definir...", MNID_BKMK_DEFINE + } + POPUP "Aj&uda" { + MENUITEM "Ajuda &na ajuda", MNID_HELP_HELPON + MENUITEM "Sempre &visvel", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Informaes...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "&Sobre WINE", MNID_HELP_WINE +#endif + } +} + +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE + +MAIN_MENU MENU +{ + POPUP "&Ficheiro" { + MENUITEM "&Abrir...", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&Imprimir", MNID_FILE_PRINT + MENUITEM "&Configurar Impressora...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "Sai&r", MNID_FILE_EXIT + } + POPUP "&Editar" { + MENUITEM "&Copiar...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Anotar...", MNID_EDIT_ANNOTATE + } + POPUP "In&dicador" { + MENUITEM "&Definir...", MNID_BKMK_DEFINE + } + POPUP "Aj&uda" { + MENUITEM "Ajuda &na ajuda", MNID_HELP_HELPON + MENUITEM "Sempre &visvel", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Informaes...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "&Acerca do WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ + +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN + +STRINGTABLE DISCARDABLE +{ +STID_WINE_HELP, "Ajuda WINE" +STID_WHERROR, "ERRO" +STID_WARNING, "AVISO" +STID_INFO, "Informao" +STID_NOT_IMPLEMENTED, "No implementado" +STID_HLPFILE_ERROR_s, "Erro encontrado na leitura do arquivo de ajuda '%s'" +STID_CONTENTS, "&Contedo" +STID_SEARCH, "&Procurar" +STID_BACK, "&Voltar" +STID_HISTORY, "&Histrico" +STID_TOPICS, "&Tpicos" +STID_ALL_FILES, "Todos os arquivos (*.*)" +STID_HELP_FILES_HLP, "Arquivos de ajuda (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} + +LANGUAGE LANG_PORTUGUESE, SUBLANG_PORTUGUESE + +STRINGTABLE DISCARDABLE +{ +STID_WINE_HELP, "Ajuda WINE" +STID_WHERROR, "ERRO" +STID_WARNING, "AVISO" +STID_INFO, "Informao" +STID_NOT_IMPLEMENTED, "No implementado" +STID_HLPFILE_ERROR_s, "Erro encontrado na leitura do ficheiro de ajuda '%s'" +STID_CONTENTS, "&Contedo" +STID_SEARCH, "&Procurar" +STID_BACK, "&Voltar" +STID_HISTORY, "&Histrico" +STID_TOPICS, "&Tpicos" +STID_ALL_FILES, "Todos os ficheiros (*.*)" +STID_HELP_FILES_HLP, "Ficheiros de ajuda (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Ru.rc b/reactos/base/applications/winhelp/Ru.rc new file mode 100644 index 00000000000..c07a74362e3 --- /dev/null +++ b/reactos/base/applications/winhelp/Ru.rc @@ -0,0 +1,69 @@ +/* + * Help Viewer (Russian resources) + * + * Copyright 2003 Igor Stepin + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +{ + POPUP "&" { + MENUITEM "&", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&", MNID_FILE_PRINT + MENUITEM " &...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&", MNID_FILE_EXIT + } + POPUP "&" { + MENUITEM "&...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&...", MNID_EDIT_ANNOTATE + } + POPUP "&" { + MENUITEM "&...", MNID_BKMK_DEFINE + } + POPUP "&" { + MENUITEM " & ", MNID_HELP_HELPON + MENUITEM " &", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "& Wine", MNID_HELP_WINE +#endif + } +} + +/* Strings */ +STRINGTABLE DISCARDABLE LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +{ +STID_WINE_HELP, " WINE" +STID_WHERROR, "" +STID_WARNING, "" +STID_INFO, "" +STID_NOT_IMPLEMENTED, " " +STID_HLPFILE_ERROR_s, " `%s'" +STID_CONTENTS, "&" +STID_SEARCH, "&" +STID_BACK, "&" +STID_HISTORY, "&" +STID_TOPICS, "&" +STID_ALL_FILES, " (*.*)" +STID_HELP_FILES_HLP, " (*.hlp)" +STID_FILE_NOT_FOUND_s " '%s'. ?" +} diff --git a/reactos/base/applications/winhelp/Si.rc b/reactos/base/applications/winhelp/Si.rc new file mode 100644 index 00000000000..d587908cdd9 --- /dev/null +++ b/reactos/base/applications/winhelp/Si.rc @@ -0,0 +1,69 @@ +/* + * Help Viewer (Slovenian Resources) + * + * Copyright 2002-2003 Rok Mandeljc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT +{ + POPUP "&Datoteka" { + MENUITEM "&Odpri ...", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "Na&tisni temo ...", MNID_FILE_PRINT + MENUITEM "&Priprava tiskalnika", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "Iz&hod", MNID_FILE_EXIT + } + POPUP "&Urejanje" { + MENUITEM "&Kopiraj", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Pripombe ...", MNID_EDIT_ANNOTATE + } + POPUP "&Zaznamek" { + MENUITEM "&Doloi ...", MNID_BKMK_DEFINE + } + POPUP "&Pomo" { + MENUITEM "&O pomoi", MNID_HELP_HELPON + MENUITEM "Vedno na &vrhu", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Informacije ...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "&O WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ +STRINGTABLE DISCARDABLE LANGUAGE LANG_SLOVENIAN, SUBLANG_DEFAULT +{ +STID_WINE_HELP, "WINE Pomo" +STID_WHERROR, "NAPAKA" +STID_WARNING, "OPOZORILO" +STID_INFO, "Informacija" +STID_NOT_IMPLEMENTED, "Ni (e) na voljo" +STID_HLPFILE_ERROR_s, "Napaka pri branju datoteke `%s'" +STID_CONTENTS, "&Teme pomoi" +STID_SEARCH, "&Iskanje" +STID_BACK, "&Nazaj" +STID_HISTORY, "&Zgodovina" +STID_TOPICS, "&Vsebina" +STID_ALL_FILES, "Vse datiteke (*.*)" +STID_HELP_FILES_HLP, "Datoteke s pomojo (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Sk.rc b/reactos/base/applications/winhelp/Sk.rc new file mode 100644 index 00000000000..c8e713f9b38 --- /dev/null +++ b/reactos/base/applications/winhelp/Sk.rc @@ -0,0 +1,66 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +MAIN_MENU MENU LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT +{ + POPUP "&Sbor" { + MENUITEM "&Otvori...", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&Tlai", MNID_FILE_PRINT + MENUITEM "&Nastavenie tlae...", MNID_FILE_SETUP + MENUITEM "U&koni", MNID_FILE_EXIT + } + POPUP "&Upravi" { + MENUITEM "Kop&rova...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Skomentova...", MNID_EDIT_ANNOTATE + } + POPUP "&Zloka" { + MENUITEM "&Definova...", MNID_BKMK_DEFINE + } + POPUP "&Pomoc" { + MENUITEM "Pomoc &na pomoci", MNID_HELP_HELPON + MENUITEM "Vdy na &vrchu", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Info...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "O& WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ +STRINGTABLE DISCARDABLE LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT +{ +STID_WINE_HELP, "WINE Pomoc" +STID_WHERROR, "CHYBA" +STID_WARNING, "VAROVANIE" +STID_INFO, "Informcie" +STID_NOT_IMPLEMENTED, "Neimplementovan" +STID_HLPFILE_ERROR_s, "Chyba poas tania sboru `%s'" +STID_CONTENTS, "&Obsah" +STID_SEARCH, "&Hada" +STID_BACK, "&Sp" +STID_HISTORY, "&Histria" +STID_TOPICS, "&Topics" +STID_ALL_FILES, "Vetky sbory (*.*)" +STID_HELP_FILES_HLP, "Sbory pomoci (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Sw.rc b/reactos/base/applications/winhelp/Sw.rc new file mode 100644 index 00000000000..84da4f99ad7 --- /dev/null +++ b/reactos/base/applications/winhelp/Sw.rc @@ -0,0 +1,72 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Swedish language by Karl Backstrm + * Copyright 2002 Sylvain Petreolle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT +{ + POPUP "&Arkiv" { + MENUITEM "&ppna...", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&Skriv ut", MNID_FILE_PRINT + MENUITEM "Skrivar &instllningar...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&Avsluta", MNID_FILE_EXIT + } + POPUP "&Redigera" { + MENUITEM "&Kopiera...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Markera...", MNID_EDIT_ANNOTATE + } + POPUP "&Bokmrke" { + MENUITEM "&Defingera...", MNID_BKMK_DEFINE + } + POPUP "&Hjlp" { + MENUITEM "Anvndningen &av hjlp", MNID_HELP_HELPON + MENUITEM "Alltid &verst", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Information...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "&Om WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ + +STRINGTABLE DISCARDABLE LANGUAGE LANG_SWEDISH, SUBLANG_DEFAULT +{ +STID_WINE_HELP, "WINE Hjlp" +STID_WHERROR, "FEL" +STID_WARNING, "VARNING" +STID_INFO, "Information" +STID_NOT_IMPLEMENTED, "Ej implementererat" +STID_HLPFILE_ERROR_s, "FEL vid lsning av hjlp filen `%s'" +STID_CONTENTS, "&Innehll" +STID_SEARCH, "&Sk" +STID_BACK, "&Tillbaka" +STID_HISTORY, "&versikt" +STID_TOPICS, "T&opics" +STID_ALL_FILES, "Alla filer (*.*))" +STID_HELP_FILES_HLP, "Hjlp filer (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Tr.rc b/reactos/base/applications/winhelp/Tr.rc new file mode 100644 index 00000000000..9578e8b7e1e --- /dev/null +++ b/reactos/base/applications/winhelp/Tr.rc @@ -0,0 +1,69 @@ +/* + * Turkish Resources for Help Viewer + * + * Copyright 2006 Fatih Ac + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT +{ + POPUP "&Dosya" { + MENUITEM "&A", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "Ya&zdr", MNID_FILE_PRINT + MENUITEM "&Yazc ayarlar...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&k", MNID_FILE_EXIT + } + POPUP "D&zen" { + MENUITEM "K&opyala...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Annotate...", MNID_EDIT_ANNOTATE + } + POPUP "Yer &mleri" { + MENUITEM "&Tanmla...", MNID_BKMK_DEFINE + } + POPUP "&Yardm" { + MENUITEM "&Yardm Kullanm", MNID_HELP_HELPON + MENUITEM "&Her Zaman stte", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Bilgi...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "WINE &Hakknda", MNID_HELP_WINE +#endif + } +} + +/* Strings */ +STRINGTABLE DISCARDABLE LANGUAGE LANG_TURKISH, SUBLANG_DEFAULT +{ +STID_WINE_HELP, "WINE Yardm" +STID_WHERROR, "HATA" +STID_WARNING, "UYARI" +STID_INFO, "Bilgi" +STID_NOT_IMPLEMENTED, "Henz tamamlanmad" +STID_HLPFILE_ERROR_s, "'%s' yardm dosyas alrken hata" +STID_CONTENTS, "&indekiler" +STID_SEARCH, "&Ara" +STID_BACK, "&Geri" +STID_HISTORY, "Ge&mi" +STID_TOPICS, "&Konular" +STID_ALL_FILES, "Tm dosyalar (*.*)" +STID_HELP_FILES_HLP, "Yardm dosyalar (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Va.rc b/reactos/base/applications/winhelp/Va.rc new file mode 100644 index 00000000000..647c9df5eda --- /dev/null +++ b/reactos/base/applications/winhelp/Va.rc @@ -0,0 +1,76 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Rumantsch Ladin (Vallader) by mbaur@g26.ethz.ch + * Copyright 2002 Sylvain Petreolle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +/* +* language : switzerland romanch +* not supported today +*/ +MAIN_MENU MENU LANGUAGE LANG_, SUBLANG_DEFAULT +{ + POPUP "&Datoteca" { + MENUITEM "&Rivir", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&Stampar tema", MNID_FILE_PRINT + MENUITEM "&Installaziun dal stampader...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "&Finir", MNID_FILE_EXIT + } + POPUP "&Lavurar" { + MENUITEM "Capchar", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Annotaziun...", MNID_EDIT_ANNOTATE + } + POPUP "&Marca" { + MENUITEM "&Definir...", MNID_BKMK_DEFINE + } + POPUP "&Agd" { + MENUITEM "&Douvrar l'agd", MNID_HELP_HELPON + MENUITEM "Adna da&vant", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "I&nfuormaziuns", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM "Davart &WINE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ + +STRINGTABLE DISCARDABLE LANGUAGE LANG_FRENCH, SUBLANG_DEFAULT +{ +WINE_HELP, "WINE agd" +WHERROR, "SBAGL" +WARNING, "ATTENZIUN" +INFO, "INFUORMAZIUN" +NOT_IMPLEMENTED, "Na implementa" +HLPFILE_ERROR_s, "Sbagl cun leger la datoteca d'agd `%s'" +CONTENTS, "&Cuntgn" +SEARCH, "&Tscherchar" +BACK, "&Inavo" +HISTORY, "&Fin qua" +TOPICS, "T&opics" +ALL_FILES, "Tuot las datotecas (*.*)" +HELP_FILES_HLP, "Datotecas d'agd (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/Wa.rc b/reactos/base/applications/winhelp/Wa.rc new file mode 100644 index 00000000000..c536d2a3f38 --- /dev/null +++ b/reactos/base/applications/winhelp/Wa.rc @@ -0,0 +1,76 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 1999 Pablo Saratxaga + * Copyright 2002 Sylvain Petreolle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifdef LANG_WALON + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_WALON, SUBLANG_DEFAULT +{ + POPUP "&Fitch" { + MENUITEM "&Drov...", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "&Rexhe", MNID_FILE_PRINT + MENUITEM "&Apontiaedje del scrirece...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "Mouss &Fo", MNID_FILE_EXIT + } + POPUP "&Candj" { + MENUITEM "&Copy...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "&Sicrre...", MNID_EDIT_ANNOTATE + } + POPUP "&Rimrkes" { + MENUITEM "&Defini...", MNID_BKMK_DEFINE + } + POPUP "&Aide" { + MENUITEM "&Aide so l' Aide", MNID_HELP_HELPON + MENUITEM "Todi &Visibe", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "&Informcion...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM " &dfait di WINEE", MNID_HELP_WINE +#endif + } +} + +/* Strings */ + +STRINGTABLE DISCARDABLE LANGUAGE LANG_WALON, SUBLANG_DEFAULT +{ +STID_WINE_HELP, "Aidance di WINE" +STID_WHERROR, "AROKE" +STID_WARNING, "ADVERTIXHMINT" +STID_INFO, "Informcion" +STID_NOT_IMPLEMENTED, "Nn co possibe" +STID_HLPFILE_ERROR_s, "Yk n' a nn st moumint di lere li fitch d' aide `%s'" +STID_CONTENTS, "&dvins" +STID_SEARCH, "C&wer" +STID_BACK, "n &Er" +STID_HISTORY, "&Istwere" +STID_TOPICS, "&Topics" +STID_ALL_FILES, "Tos les fitchs (*.*)" +STID_HELP_FILES_HLP, "Fitchs d' aide (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} + +#endif /* LANG_WALON */ diff --git a/reactos/base/applications/winhelp/Zh.rc b/reactos/base/applications/winhelp/Zh.rc new file mode 100644 index 00000000000..8c0689b5142 --- /dev/null +++ b/reactos/base/applications/winhelp/Zh.rc @@ -0,0 +1,70 @@ +/* + * Help Viewer + * Simplified Chinese Language Support + * + * Copyright 2002 liuspider + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Menu */ + +MAIN_MENU MENU LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED +{ + POPUP "ļ&F" { + MENUITEM "򿪣&O", MNID_FILE_OPEN + MENUITEM SEPARATOR + MENUITEM "ӡ&P", MNID_FILE_PRINT + MENUITEM "ӡã&S...", MNID_FILE_SETUP + MENUITEM SEPARATOR + MENUITEM "˳&E", MNID_FILE_EXIT + } + POPUP "༭&E" { + MENUITEM "ƣ&C...", MNID_EDIT_COPYDLG + MENUITEM SEPARATOR + MENUITEM "עͣ&A...", MNID_EDIT_ANNOTATE + } + POPUP "ǩ&B" { + MENUITEM "壨&D...", MNID_BKMK_DEFINE + } + POPUP "&H" { + MENUITEM "ʹð&O", MNID_HELP_HELPON + MENUITEM "ǰ棨&T", MNID_HELP_HELPTOP + MENUITEM SEPARATOR + MENUITEM "Ϣ&I...", MNID_HELP_ABOUT +#ifdef WINELIB + MENUITEM " WINE&A", MNID_HELP_WINE +#endif + } +} + +/* Strings */ +STRINGTABLE DISCARDABLE LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED +{ +STID_WINE_HELP, "WINE " +STID_WHERROR, "" +STID_WARNING, "" +STID_INFO, "Ϣ" +STID_NOT_IMPLEMENTED, "δʵ" +STID_HLPFILE_ERROR_s, "ļ %s ʱ" +STID_CONTENTS, "ݣ&C" +STID_SEARCH, "&S" +STID_BACK, "أ&B" +STID_HISTORY, "ʷ&H" +STID_TOPICS, "⣨&T" +STID_ALL_FILES, "ļ (*.*)" +STID_HELP_FILES_HLP, "ļ (*.hlp)" +STID_FILE_NOT_FOUND_s "Cannot find '%s'. Do you want to find this file yourself?" +} diff --git a/reactos/base/applications/winhelp/callback.c b/reactos/base/applications/winhelp/callback.c new file mode 100644 index 00000000000..b966039f3d6 --- /dev/null +++ b/reactos/base/applications/winhelp/callback.c @@ -0,0 +1,180 @@ +/* + * Help Viewer - DLL callback into WineHelp + * + * Copyright 2004 Eric Pouech + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define WIN32_LEAN_AND_MEAN + +#include + +#include "windows.h" +#include "winhelp.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winhelp); + +static WORD CALLBACK WHD_GetFSError(void) +{ + WINE_FIXME("()\n"); + return 0; +} + +static HANDLE CALLBACK WHD_Open(LPSTR name, BYTE flags) +{ + unsigned mode = 0; + + //WINE_FIXME("(%s %x)\n", wine_dbgstr_a(name), flags); + switch (flags) + { + case 0: mode = GENERIC_READ | GENERIC_WRITE; break; + case 2: mode = GENERIC_READ; break; + default: WINE_FIXME("Undocumented flags %x\n", flags); + } + return CreateFile(name, mode, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); +} + +static WORD CALLBACK WHD_Close(HANDLE fs) +{ + WINE_FIXME("(%p)\n", fs); + CloseHandle(fs); + return 0; +} + +static HANDLE CALLBACK WHD_OpenBag(HANDLE fs, LPSTR name, BYTE flags) +{ + WINE_FIXME("(%p %s %x)\n", fs, name, flags); + return NULL; +} + +static HANDLE CALLBACK WHD_CloseBag(HANDLE bag) +{ + WINE_FIXME("()\n"); + return NULL; +} + +static LONG CALLBACK WHD_ReadBag(HANDLE bag, BYTE* ptr, LONG len) +{ + WINE_FIXME("()\n"); + return 0; +} + +static LONG CALLBACK WHD_TellBag(HANDLE bag) +{ + WINE_FIXME("()\n"); + return 0; +} + +static LONG CALLBACK WHD_SeekBag(HANDLE bag, LONG offset, WORD whence) +{ + WINE_FIXME("()\n"); + return 0; +} + +static BOOL CALLBACK WHD_IsEofBag(HANDLE bag) +{ + WINE_FIXME("()\n"); + return FALSE; +} + +static LONG CALLBACK WHD_SizeBag(HANDLE bag) +{ + WINE_FIXME("()\n"); + return 0; +} + +static BOOL CALLBACK WHD_Access(HANDLE fs, LPSTR name, BYTE flags) +{ + WINE_FIXME("()\n"); + return FALSE; +} + +static WORD CALLBACK WHD_LLInfoFromBag(HANDLE bag, WORD opt, LPWORD p1, LPLONG p2, LPLONG p3) +{ + WINE_FIXME("()\n"); + return 0; +} + +static WORD CALLBACK WHD_LLInfoFromFile(HANDLE fs, LPSTR name, WORD opt, LPWORD p1, LPLONG p2, LPLONG p3) +{ + WINE_FIXME("()\n"); + return 0; +} + +static void CALLBACK WHD_Error(int err) +{ + WINE_FIXME("()\n"); +} + +static void CALLBACK WHD_ErrorString(LPSTR err) +{ + WINE_FIXME("()\n"); +} + +static LONG CALLBACK WHD_GetInfo(WORD what, HWND hnd) +{ + LONG ret = 0; + + WINE_TRACE("(%x %p)\n", what, hnd); + switch (what) + { + case 0: break; + case 1: /* instance */ ret = (LONG)Globals.hInstance; break; + case 3: /* current window */ ret = (LONG)Globals.active_win->hMainWnd; break; + case 2: /* main window */ + case 4: /* handle to opened file */ + case 5: /* foreground color */ + case 6: /* background color */ + case 7: /* topic number */ + case 8: /* current opened file name */ + WINE_FIXME("NIY %u\n", what); + break; + default: + WINE_FIXME("Undocumented %u\n", what); + break; + } + return ret; +} + +static LONG CALLBACK WHD_API(LPSTR x, WORD xx, DWORD xxx) +{ + WINE_FIXME("()\n"); + return 0; +} + +FARPROC Callbacks[] = +{ + (FARPROC)WHD_GetFSError, + (FARPROC)WHD_Open, + (FARPROC)WHD_Close, + (FARPROC)WHD_OpenBag, + (FARPROC)WHD_CloseBag, + (FARPROC)WHD_ReadBag, + (FARPROC)WHD_TellBag, + (FARPROC)WHD_SeekBag, + (FARPROC)WHD_IsEofBag, + (FARPROC)WHD_SizeBag, + (FARPROC)WHD_Access, + (FARPROC)WHD_LLInfoFromBag, + (FARPROC)WHD_LLInfoFromFile, + (FARPROC)WHD_Error, + (FARPROC)WHD_ErrorString, + (FARPROC)WHD_GetInfo, + (FARPROC)WHD_API +}; diff --git a/reactos/base/applications/winhelp/hlpfile.c b/reactos/base/applications/winhelp/hlpfile.c new file mode 100644 index 00000000000..c6ff1b50161 --- /dev/null +++ b/reactos/base/applications/winhelp/hlpfile.c @@ -0,0 +1,2065 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * 2002 Eric Pouech + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winhelp.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winhelp); + +static inline unsigned short GET_USHORT(const BYTE* buffer, unsigned i) +{ + return (BYTE)buffer[i] + 0x100 * (BYTE)buffer[i + 1]; +} + +static inline short GET_SHORT(const BYTE* buffer, unsigned i) +{ + return (BYTE)buffer[i] + 0x100 * (signed char)buffer[i+1]; +} + +static inline unsigned GET_UINT(const BYTE* buffer, unsigned i) +{ + return GET_USHORT(buffer, i) + 0x10000 * GET_USHORT(buffer, i + 2); +} + +static HLPFILE *first_hlpfile = 0; +static BYTE *file_buffer; + +static struct +{ + UINT num; + unsigned* offsets; + char* buffer; +} phrases; + +static struct +{ + BYTE** map; + BYTE* end; + UINT wMapLen; +} topic; + +static struct +{ + UINT wFont; + UINT wIndent; + UINT wHSpace; + UINT wVSpace; + HLPFILE_LINK* link; +} attributes; + +static BOOL HLPFILE_DoReadHlpFile(HLPFILE*, LPCSTR); +static BOOL HLPFILE_ReadFileToBuffer(HFILE); +static BOOL HLPFILE_FindSubFile(LPCSTR name, BYTE**, BYTE**); +static BOOL HLPFILE_SystemCommands(HLPFILE*); +static INT HLPFILE_UncompressedLZ77_Size(BYTE *ptr, BYTE *end); +static BYTE* HLPFILE_UncompressLZ77(BYTE *ptr, BYTE *end, BYTE *newptr); +static BOOL HLPFILE_UncompressLZ77_Phrases(HLPFILE*); +static BOOL HLPFILE_Uncompress_Phrases40(HLPFILE*); +static BOOL HLPFILE_Uncompress_Topic(HLPFILE*); +static BOOL HLPFILE_GetContext(HLPFILE*); +static BOOL HLPFILE_GetMap(HLPFILE*); +static BOOL HLPFILE_AddPage(HLPFILE*, BYTE*, BYTE*, unsigned); +static BOOL HLPFILE_AddParagraph(HLPFILE*, BYTE *, BYTE*, unsigned*); +static void HLPFILE_Uncompress2(const BYTE*, const BYTE*, BYTE*, const BYTE*); +static BOOL HLPFILE_Uncompress3(char*, const char*, const BYTE*, const BYTE*); +static void HLPFILE_UncompressRLE(const BYTE* src, const BYTE* end, BYTE** dst, unsigned dstsz); +static BOOL HLPFILE_ReadFont(HLPFILE* hlpfile); + +#if 0 +/*********************************************************************** + * + * HLPFILE_PageByNumber + */ +static HLPFILE_PAGE *HLPFILE_PageByNumber(LPCSTR lpszPath, UINT wNum) +{ + HLPFILE_PAGE *page; + HLPFILE *hlpfile = HLPFILE_ReadHlpFile(lpszPath); + + if (!hlpfile) return 0; + + WINE_TRACE("[%s/%u]\n", lpszPath, wNum); + + for (page = hlpfile->first_page; page && wNum; page = page->next) wNum--; + + /* HLPFILE_FreeHlpFile(lpszPath); */ + + return page; +} +#endif + +/* FIXME: + * this finds the page containing the offset. The offset can either + * refer to the top of the page (offset == page->offset), or + * to some paragraph inside the page... + * As of today, we only return the page... we should also return + * a paragraph, and then, while opening a new page, compute the + * y-offset of the paragraph to be shown and scroll the window + * accordinly + */ +/****************************************************************** + * HLPFILE_PageByOffset + * + * + */ +HLPFILE_PAGE *HLPFILE_PageByOffset(HLPFILE* hlpfile, LONG offset) +{ + HLPFILE_PAGE* page; + HLPFILE_PAGE* found; + + if (!hlpfile) return 0; + + WINE_TRACE("<%s>[%x]\n", hlpfile->lpszPath, offset); + + if (offset == 0xFFFFFFFF) return NULL; + page = NULL; + + for (found = NULL, page = hlpfile->first_page; page; page = page->next) + { + if (page->offset <= offset && (!found || found->offset < page->offset)) + found = page; + } + if (!found) + WINE_ERR("Page of offset %u not found in file %s\n", + offset, hlpfile->lpszPath); + return found; +} + +/*********************************************************************** + * + * HLPFILE_HlpFilePageByHash + */ +HLPFILE_PAGE *HLPFILE_PageByHash(HLPFILE* hlpfile, LONG lHash) +{ + int i; + + if (!hlpfile) return 0; + + WINE_TRACE("<%s>[%x]\n", hlpfile->lpszPath, lHash); + + for (i = 0; i < hlpfile->wContextLen; i++) + { + if (hlpfile->Context[i].lHash == lHash) + return HLPFILE_PageByOffset(hlpfile, hlpfile->Context[i].offset); + } + + WINE_ERR("Page of hash %x not found in file %s\n", lHash, hlpfile->lpszPath); + return NULL; +} + +/*********************************************************************** + * + * HLPFILE_PageByMap + */ +HLPFILE_PAGE *HLPFILE_PageByMap(HLPFILE* hlpfile, LONG lMap) +{ + int i; + + if (!hlpfile) return 0; + + WINE_TRACE("<%s>[%x]\n", hlpfile->lpszPath, lMap); + + for (i = 0; i < hlpfile->wMapLen; i++) + { + if (hlpfile->Map[i].lMap == lMap) + return HLPFILE_PageByOffset(hlpfile, hlpfile->Map[i].offset); + } + + WINE_ERR("Page of Map %x not found in file %s\n", lMap, hlpfile->lpszPath); + return NULL; +} + +/*********************************************************************** + * + * HLPFILE_Contents + */ +HLPFILE_PAGE* HLPFILE_Contents(HLPFILE *hlpfile) +{ + HLPFILE_PAGE* page = NULL; + + if (!hlpfile) return NULL; + + page = HLPFILE_PageByOffset(hlpfile, hlpfile->contents_start); + if (!page) page = hlpfile->first_page; + return page; +} + +/*********************************************************************** + * + * HLPFILE_Hash + */ +LONG HLPFILE_Hash(LPCSTR lpszContext) +{ + LONG lHash = 0; + CHAR c; + + while ((c = *lpszContext++)) + { + CHAR x = 0; + if (c >= 'A' && c <= 'Z') x = c - 'A' + 17; + if (c >= 'a' && c <= 'z') x = c - 'a' + 17; + if (c >= '1' && c <= '9') x = c - '0'; + if (c == '0') x = 10; + if (c == '.') x = 12; + if (c == '_') x = 13; + if (x) lHash = lHash * 43 + x; + } + return lHash; +} + +/*********************************************************************** + * + * HLPFILE_ReadHlpFile + */ +HLPFILE *HLPFILE_ReadHlpFile(LPCSTR lpszPath) +{ + HLPFILE* hlpfile; + + for (hlpfile = first_hlpfile; hlpfile; hlpfile = hlpfile->next) + { + if (!strcmp(lpszPath, hlpfile->lpszPath)) + { + hlpfile->wRefCount++; + return hlpfile; + } + } + + hlpfile = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE) + lstrlen(lpszPath) + 1); + if (!hlpfile) return 0; + + hlpfile->lpszPath = (char*)hlpfile + sizeof(HLPFILE); + hlpfile->lpszTitle = NULL; + hlpfile->lpszCopyright = NULL; + hlpfile->first_page = NULL; + hlpfile->first_macro = NULL; + hlpfile->wContextLen = 0; + hlpfile->Context = NULL; + hlpfile->wMapLen = 0; + hlpfile->Map = NULL; + hlpfile->contents_start = 0xFFFFFFFF; + hlpfile->prev = NULL; + hlpfile->next = first_hlpfile; + hlpfile->wRefCount = 1; + + hlpfile->numBmps = 0; + hlpfile->bmps = NULL; + + hlpfile->numFonts = 0; + hlpfile->fonts = NULL; + + hlpfile->numWindows = 0; + hlpfile->windows = NULL; + + strcpy(hlpfile->lpszPath, lpszPath); + + first_hlpfile = hlpfile; + if (hlpfile->next) hlpfile->next->prev = hlpfile; + + phrases.offsets = NULL; + phrases.buffer = NULL; + topic.map = NULL; + topic.end = NULL; + file_buffer = NULL; + + if (!HLPFILE_DoReadHlpFile(hlpfile, lpszPath)) + { + HLPFILE_FreeHlpFile(hlpfile); + hlpfile = 0; + } + + HeapFree(GetProcessHeap(), 0, phrases.offsets); + HeapFree(GetProcessHeap(), 0, phrases.buffer); + HeapFree(GetProcessHeap(), 0, topic.map); + HeapFree(GetProcessHeap(), 0, file_buffer); + + return hlpfile; +} + +/*********************************************************************** + * + * HLPFILE_DoReadHlpFile + */ +static BOOL HLPFILE_DoReadHlpFile(HLPFILE *hlpfile, LPCSTR lpszPath) +{ + BOOL ret; + HFILE hFile; + OFSTRUCT ofs; + BYTE* buf; + DWORD ref = 0x0C; + unsigned index, old_index, offset, len, offs; + + hFile = OpenFile(lpszPath, &ofs, OF_READ); + if (hFile == HFILE_ERROR) return FALSE; + + ret = HLPFILE_ReadFileToBuffer(hFile); + _lclose(hFile); + if (!ret) return FALSE; + + if (!HLPFILE_SystemCommands(hlpfile)) return FALSE; + + /* load phrases support */ + if (!HLPFILE_UncompressLZ77_Phrases(hlpfile)) + HLPFILE_Uncompress_Phrases40(hlpfile); + + if (!HLPFILE_Uncompress_Topic(hlpfile)) return FALSE; + if (!HLPFILE_ReadFont(hlpfile)) return FALSE; + + buf = topic.map[0]; + old_index = -1; + offs = 0; + do + { + BYTE* end; + + /* FIXME this depends on the blocksize, can be 2k in some cases */ + index = (ref - 0x0C) >> 14; + offset = (ref - 0x0C) & 0x3fff; + + WINE_TRACE("ref=%08x => [%u/%u]\n", ref, index, offset); + + if (index >= topic.wMapLen) {WINE_WARN("maplen\n"); break;} + buf = topic.map[index] + offset; + if (buf + 0x15 >= topic.end) {WINE_WARN("extra\n"); break;} + end = min(buf + GET_UINT(buf, 0), topic.end); + if (index != old_index) {offs = 0; old_index = index;} + + switch (buf[0x14]) + { + case 0x02: + if (!HLPFILE_AddPage(hlpfile, buf, end, index * 0x8000L + offs)) return FALSE; + break; + + case 0x20: + if (!HLPFILE_AddParagraph(hlpfile, buf, end, &len)) return FALSE; + offs += len; + break; + + case 0x23: + if (!HLPFILE_AddParagraph(hlpfile, buf, end, &len)) return FALSE; + offs += len; + break; + + default: + WINE_ERR("buf[0x14] = %x\n", buf[0x14]); + } + + ref = GET_UINT(buf, 0xc); + } while (ref != 0xffffffff); + + HLPFILE_GetMap(hlpfile); + return HLPFILE_GetContext(hlpfile); +} + +/*********************************************************************** + * + * HLPFILE_AddPage + */ +static BOOL HLPFILE_AddPage(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned offset) +{ + HLPFILE_PAGE* page; + BYTE* title; + UINT titlesize; + char* ptr; + HLPFILE_MACRO*macro; + + if (buf + 0x31 > end) {WINE_WARN("page1\n"); return FALSE;}; + title = buf + GET_UINT(buf, 0x10); + if (title > end) {WINE_WARN("page2\n"); return FALSE;}; + + titlesize = GET_UINT(buf, 4); + page = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_PAGE) + titlesize + 1); + if (!page) return FALSE; + page->lpszTitle = (char*)page + sizeof(HLPFILE_PAGE); + + if (hlpfile->hasPhrases) + { + HLPFILE_Uncompress2(title, end, (BYTE*)page->lpszTitle, (BYTE*)page->lpszTitle + titlesize); + } + else + { + if (GET_UINT(buf, 0x4) > GET_UINT(buf, 0) - GET_UINT(buf, 0x10)) + { + /* need to decompress */ + HLPFILE_Uncompress3(page->lpszTitle, page->lpszTitle + titlesize, + title, end); + } + else + { + memcpy(page->lpszTitle, title, titlesize); + } + } + + page->lpszTitle[titlesize] = '\0'; + + if (hlpfile->first_page) + { + HLPFILE_PAGE *p; + + for (p = hlpfile->first_page; p->next; p = p->next); + page->prev = p; + p->next = page; + } + else + { + hlpfile->first_page = page; + page->prev = NULL; + } + + page->file = hlpfile; + page->next = NULL; + page->first_paragraph = NULL; + page->first_macro = NULL; + page->wNumber = GET_UINT(buf, 0x21); + page->offset = offset; + + page->browse_bwd = GET_UINT(buf, 0x19); + page->browse_fwd = GET_UINT(buf, 0x1D); + + WINE_TRACE("Added page[%d]: title='%s' %08x << %08x >> %08x\n", + page->wNumber, page->lpszTitle, + page->browse_bwd, page->offset, page->browse_fwd); + + memset(&attributes, 0, sizeof(attributes)); + + /* now load macros */ + ptr = page->lpszTitle + strlen(page->lpszTitle) + 1; + while (ptr < page->lpszTitle + titlesize) + { + unsigned len = strlen(ptr); + char* macro_str; + + WINE_TRACE("macro: %s\n", ptr); + macro = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_MACRO) + len + 1); + macro->lpszMacro = macro_str = (char*)(macro + 1); + memcpy(macro_str, ptr, len + 1); + /* FIXME: shall we really link macro in reverse order ?? + * may produce strange results when played at page opening + */ + macro->next = page->first_macro; + page->first_macro = macro; + ptr += len + 1; + } + + return TRUE; +} + +static long fetch_long(BYTE** ptr) +{ + long ret; + + if (*(*ptr) & 1) + { + ret = (*(unsigned long*)(*ptr) - 0x80000000L) / 2; + (*ptr) += 4; + } + else + { + ret = (*(unsigned short*)(*ptr) - 0x8000) / 2; + (*ptr) += 2; + } + + return ret; +} + +static unsigned long fetch_ulong(BYTE** ptr) +{ + unsigned long ret; + + if (*(*ptr) & 1) + { + ret = *(unsigned long*)(*ptr) / 2; + (*ptr) += 4; + } + else + { + ret = *(unsigned short*)(*ptr) / 2; + (*ptr) += 2; + } + return ret; +} + +static short fetch_short(BYTE** ptr) +{ + short ret; + + if (*(*ptr) & 1) + { + ret = (*(unsigned short*)(*ptr) - 0x8000) / 2; + (*ptr) += 2; + } + else + { + ret = (*(unsigned char*)(*ptr) - 0x80) / 2; + (*ptr)++; + } + return ret; +} + +static unsigned short fetch_ushort(BYTE** ptr) +{ + unsigned short ret; + + if (*(*ptr) & 1) + { + ret = *(unsigned short*)(*ptr) / 2; + (*ptr) += 2; + } + else + { + ret = *(unsigned char*)(*ptr) / 2; + (*ptr)++; + } + return ret; +} + +/****************************************************************** + * HLPFILE_DecompressGfx + * + * Decompress the data part of a bitmap or a metafile + */ +static BYTE* HLPFILE_DecompressGfx(BYTE* src, unsigned csz, unsigned sz, BYTE packing) +{ + BYTE* dst; + BYTE* tmp; + BYTE* tmp2; + unsigned sz77; + + WINE_TRACE("Unpacking (%d) from %u bytes to %u bytes\n", packing, csz, sz); + + switch (packing) + { + case 0: /* uncompressed */ + if (sz != csz) + WINE_WARN("Bogus gfx sizes (uncompressed): %u / %u\n", sz, csz); + dst = src; + break; + case 1: /* RunLen */ + tmp = dst = HeapAlloc(GetProcessHeap(), 0, sz); + if (!dst) return NULL; + HLPFILE_UncompressRLE(src, src + csz, &tmp, sz); + if (tmp - dst != sz) + WINE_WARN("Bogus gfx sizes (RunLen): %u/%u\n", tmp - dst, sz); + break; + case 2: /* LZ77 */ + sz77 = HLPFILE_UncompressedLZ77_Size(src, src + csz); + dst = HeapAlloc(GetProcessHeap(), 0, sz77); + if (!dst) return NULL; + HLPFILE_UncompressLZ77(src, src + csz, dst); + if (sz77 != sz) + WINE_WARN("Bogus gfx sizes (LZ77): %u / %u\n", sz77, sz); + break; + case 3: /* LZ77 then RLE */ + sz77 = HLPFILE_UncompressedLZ77_Size(src, src + csz); + tmp = HeapAlloc(GetProcessHeap(), 0, sz77); + if (!tmp) return FALSE; + HLPFILE_UncompressLZ77(src, src + csz, tmp); + dst = tmp2 = HeapAlloc(GetProcessHeap(), 0, sz); + if (!dst) return FALSE; + HLPFILE_UncompressRLE(tmp, tmp + sz77, &tmp2, sz); + if (tmp2 - dst != sz) + WINE_WARN("Bogus gfx sizes (LZ77+RunLen): %u / %u\n", tmp2 - dst, sz); + HeapFree(GetProcessHeap(), 0, tmp); + break; + default: + WINE_FIXME("Unsupported packing %u\n", packing); + return NULL; + } + return dst; +} + +/****************************************************************** + * HLPFILE_LoadBitmap + * + * + */ +static BOOL HLPFILE_LoadBitmap(BYTE* beg, BYTE type, BYTE pack, + HLPFILE_PARAGRAPH* paragraph) +{ + BYTE* ptr; + BYTE* pict_beg; + BITMAPINFO* bi; + unsigned long off, csz; + HDC hdc; + + bi = HeapAlloc(GetProcessHeap(), 0, sizeof(*bi)); + if (!bi) return FALSE; + + ptr = beg + 2; /* for type and pack */ + + bi->bmiHeader.biSize = sizeof(bi->bmiHeader); + bi->bmiHeader.biXPelsPerMeter = fetch_ulong(&ptr); + bi->bmiHeader.biYPelsPerMeter = fetch_ulong(&ptr); + bi->bmiHeader.biPlanes = fetch_ushort(&ptr); + bi->bmiHeader.biBitCount = fetch_ushort(&ptr); + bi->bmiHeader.biWidth = fetch_ulong(&ptr); + bi->bmiHeader.biHeight = fetch_ulong(&ptr); + bi->bmiHeader.biClrUsed = fetch_ulong(&ptr); + bi->bmiHeader.biClrImportant = fetch_ulong(&ptr); + bi->bmiHeader.biCompression = BI_RGB; + if (bi->bmiHeader.biBitCount > 32) WINE_FIXME("Unknown bit count %u\n", bi->bmiHeader.biBitCount); + if (bi->bmiHeader.biPlanes != 1) WINE_FIXME("Unsupported planes %u\n", bi->bmiHeader.biPlanes); + bi->bmiHeader.biSizeImage = (((bi->bmiHeader.biWidth * bi->bmiHeader.biBitCount + 31) & ~31) / 8) * bi->bmiHeader.biHeight; + WINE_TRACE("planes=%d bc=%d size=(%d,%d)\n", + bi->bmiHeader.biPlanes, bi->bmiHeader.biBitCount, + bi->bmiHeader.biWidth, bi->bmiHeader.biHeight); + + csz = fetch_ulong(&ptr); + fetch_ulong(&ptr); /* hotspot size */ + + off = GET_UINT(ptr, 0); ptr += 4; + /* GET_UINT(ptr, 0); hotspot offset */ ptr += 4; + + /* now read palette info */ + if (type == 0x06) + { + unsigned nc = bi->bmiHeader.biClrUsed; + unsigned i; + + /* not quite right, especially for bitfields type of compression */ + if (!nc && bi->bmiHeader.biBitCount <= 8) + nc = 1 << bi->bmiHeader.biBitCount; + + bi = HeapReAlloc(GetProcessHeap(), 0, bi, sizeof(*bi) + nc * sizeof(RGBQUAD)); + if (!bi) return FALSE; + for (i = 0; i < nc; i++) + { + bi->bmiColors[i].rgbBlue = ptr[0]; + bi->bmiColors[i].rgbGreen = ptr[1]; + bi->bmiColors[i].rgbRed = ptr[2]; + bi->bmiColors[i].rgbReserved = 0; + ptr += 4; + } + } + pict_beg = HLPFILE_DecompressGfx(beg + off, csz, bi->bmiHeader.biSizeImage, pack); + + paragraph->u.gfx.u.bmp.hBitmap = CreateDIBitmap(hdc = GetDC(0), &bi->bmiHeader, + CBM_INIT, pict_beg, + bi, DIB_RGB_COLORS); + ReleaseDC(0, hdc); + if (!paragraph->u.gfx.u.bmp.hBitmap) + WINE_ERR("Couldn't create bitmap\n"); + + HeapFree(GetProcessHeap(), 0, bi); + if (pict_beg != beg + off) HeapFree(GetProcessHeap(), 0, pict_beg); + + return TRUE; +} + +/****************************************************************** + * HLPFILE_LoadMetaFile + * + * + */ +static BOOL HLPFILE_LoadMetaFile(BYTE* beg, BYTE pack, HLPFILE_PARAGRAPH* paragraph) +{ + BYTE* ptr; + unsigned long size, csize; + unsigned long off, hsoff; + BYTE* bits; + LPMETAFILEPICT lpmfp; + + WINE_TRACE("Loading metafile\n"); + + ptr = beg + 2; /* for type and pack */ + + lpmfp = ¶graph->u.gfx.u.mfp; + lpmfp->mm = fetch_ushort(&ptr); /* mapping mode */ + + lpmfp->xExt = GET_USHORT(ptr, 0); + lpmfp->yExt = GET_USHORT(ptr, 2); + ptr += 4; + + size = fetch_ulong(&ptr); /* decompressed size */ + csize = fetch_ulong(&ptr); /* compressed size */ + fetch_ulong(&ptr); /* hotspot size */ + off = GET_UINT(ptr, 0); + hsoff = GET_UINT(ptr, 4); + ptr += 8; + + WINE_TRACE("sz=%lu csz=%lu (%d,%d) offs=%lu/%u,%lu\n", + size, csize, lpmfp->xExt, lpmfp->yExt, off, ptr - beg, hsoff); + + bits = HLPFILE_DecompressGfx(beg + off, csize, size, pack); + if (!bits) return FALSE; + + paragraph->cookie = para_metafile; + + lpmfp->hMF = SetMetaFileBitsEx(size, bits); + + if (!lpmfp->hMF) + WINE_FIXME("Couldn't load metafile\n"); + + if (bits != beg + off) HeapFree(GetProcessHeap(), 0, bits); + + return TRUE; +} + +/****************************************************************** + * HLPFILE_LoadGfxByAddr + * + * + */ +static BOOL HLPFILE_LoadGfxByAddr(HLPFILE *hlpfile, BYTE* ref, + unsigned long size, + HLPFILE_PARAGRAPH* paragraph) +{ + unsigned i, numpict; + + numpict = GET_USHORT(ref, 2); + WINE_TRACE("Got picture magic=%04x #=%d\n", + GET_USHORT(ref, 0), numpict); + + for (i = 0; i < numpict; i++) + { + BYTE* beg; + BYTE* ptr; + BYTE type, pack; + + WINE_TRACE("Offset[%d] = %x\n", i, GET_UINT(ref, (1 + i) * 4)); + beg = ptr = ref + GET_UINT(ref, (1 + i) * 4); + + type = *ptr++; + pack = *ptr++; + + switch (type) + { + case 5: /* device dependent bmp */ + case 6: /* device independent bmp */ + HLPFILE_LoadBitmap(beg, type, pack, paragraph); + break; + case 8: + HLPFILE_LoadMetaFile(beg, pack, paragraph); + break; + default: WINE_FIXME("Unknown type %u\n", type); return FALSE; + } + + /* FIXME: hotspots */ + + /* FIXME: implement support for multiple picture format */ + if (numpict != 1) WINE_FIXME("Supporting only one bitmap format per logical bitmap (for now). Using first format\n"); + break; + } + return TRUE; +} + +/****************************************************************** + * HLPFILE_LoadGfxByIndex + * + * + */ +static BOOL HLPFILE_LoadGfxByIndex(HLPFILE *hlpfile, unsigned index, + HLPFILE_PARAGRAPH* paragraph) +{ + char tmp[16]; + BYTE *ref, *end; + BOOL ret; + + WINE_TRACE("Loading picture #%d\n", index); + + if (index < hlpfile->numBmps && hlpfile->bmps[index] != NULL) + { + paragraph->u.gfx.u.bmp.hBitmap = hlpfile->bmps[index]; + return TRUE; + } + + sprintf(tmp, "|bm%u", index); + + if (!HLPFILE_FindSubFile(tmp, &ref, &end)) {WINE_WARN("no sub file\n"); return FALSE;} + + ref += 9; + + ret = HLPFILE_LoadGfxByAddr(hlpfile, ref, end - ref, paragraph); + + /* cache bitmap */ + if (ret && paragraph->cookie == para_bitmap) + { + if (index >= hlpfile->numBmps) + { + hlpfile->numBmps = index + 1; + if (hlpfile->bmps) + hlpfile->bmps = HeapReAlloc(GetProcessHeap(), 0, hlpfile->bmps, + hlpfile->numBmps * sizeof(hlpfile->bmps[0])); + else + hlpfile->bmps = HeapAlloc(GetProcessHeap(), 0, + hlpfile->numBmps * sizeof(hlpfile->bmps[0])); + + } + hlpfile->bmps[index] = paragraph->u.gfx.u.bmp.hBitmap; + } + return ret; +} + +/****************************************************************** + * HLPFILE_AllocLink + * + * + */ +static HLPFILE_LINK* HLPFILE_AllocLink(int cookie, const char* str, LONG hash, + BOOL clrChange, unsigned wnd) +{ + HLPFILE_LINK* link; + char* link_str; + + /* FIXME: should build a string table for the attributes.link.lpszPath + * they are reallocated for each link + */ + link = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_LINK) + strlen(str) + 1); + if (!link) return NULL; + + link->cookie = cookie; + link->lpszString = link_str = (char*)link + sizeof(HLPFILE_LINK); + strcpy(link_str, str); + link->lHash = hash; + link->bClrChange = clrChange ? 1 : 0; + link->window = wnd; + link->wRefCount = 1; + + WINE_TRACE("Link[%d] to %s@%08x:%d\n", + link->cookie, link->lpszString, + link->lHash, link->window); + return link; +} + +/*********************************************************************** + * + * HLPFILE_AddParagraph + */ +static BOOL HLPFILE_AddParagraph(HLPFILE *hlpfile, BYTE *buf, BYTE *end, unsigned* len) +{ + HLPFILE_PAGE *page; + HLPFILE_PARAGRAPH *paragraph, **paragraphptr; + UINT textsize; + BYTE *format, *format_end; + char *text, *text_end; + long size; + unsigned short bits; + unsigned nc, ncol = 1; + + if (!hlpfile->first_page) {WINE_WARN("no page\n"); return FALSE;}; + + for (page = hlpfile->first_page; page->next; page = page->next) /* Nothing */; + for (paragraphptr = &page->first_paragraph; *paragraphptr; + paragraphptr = &(*paragraphptr)->next) /* Nothing */; + + if (buf + 0x19 > end) {WINE_WARN("header too small\n"); return FALSE;}; + + size = GET_UINT(buf, 0x4); + text = HeapAlloc(GetProcessHeap(), 0, size); + if (!text) return FALSE; + if (hlpfile->hasPhrases) + { + HLPFILE_Uncompress2(buf + GET_UINT(buf, 0x10), end, (BYTE*)text, (BYTE*)text + size); + } + else + { + if (GET_UINT(buf, 0x4) > GET_UINT(buf, 0) - GET_UINT(buf, 0x10)) + { + /* block is compressed */ + HLPFILE_Uncompress3(text, text + size, buf + GET_UINT(buf, 0x10), end); + } + else + { + text = (char*)buf + GET_UINT(buf, 0x10); + } + } + text_end = text + size; + + format = buf + 0x15; + format_end = buf + GET_UINT(buf, 0x10); + + fetch_long(&format); + *len = fetch_ushort(&format); + + if (buf[0x14] == 0x23) + { + char type; + + ncol = *format++; + + WINE_TRACE("#cols %u\n", ncol); + type = *format++; + if (type == 0 || type == 2) + format += 2; + format += ncol * 4; + } + + for (nc = 0; nc < ncol; nc++) + { + WINE_TRACE("looking for format at offset %u for column %d\n", format - (buf + 0x15), nc); + if (buf[0x14] == 0x23) + format += 5; + format += 4; + bits = GET_USHORT(format, 0); format += 2; + if (bits & 0x0001) fetch_long(&format); + if (bits & 0x0002) fetch_short(&format); + if (bits & 0x0004) fetch_short(&format); + if (bits & 0x0008) fetch_short(&format); + if (bits & 0x0010) fetch_short(&format); + if (bits & 0x0020) fetch_short(&format); + if (bits & 0x0040) fetch_short(&format); + if (bits & 0x0100) format += 3; + if (bits & 0x0200) + { + int ntab = fetch_short(&format); + unsigned short ts; + + while (ntab-- > 0) + { + ts = fetch_ushort(&format); + if (ts & 0x4000) fetch_ushort(&format); + } + } + /* 0x0400, 0x0800 and 0x1000 don't need space */ + if ((bits & 0xE080) != 0) + WINE_FIXME("Unsupported bits %04x, potential trouble ahead\n", bits); + + while (text < text_end && format < format_end) + { + //WINE_TRACE("Got text: %s (%p/%p - %p/%p)\n", wine_dbgstr_a(text), text, text_end, format, format_end); + textsize = strlen(text) + 1; + if (textsize > 1) + { + paragraph = HeapAlloc(GetProcessHeap(), 0, + sizeof(HLPFILE_PARAGRAPH) + textsize); + if (!paragraph) return FALSE; + *paragraphptr = paragraph; + paragraphptr = ¶graph->next; + + paragraph->next = NULL; + paragraph->link = attributes.link; + if (paragraph->link) paragraph->link->wRefCount++; + paragraph->cookie = para_normal_text; + paragraph->u.text.wFont = attributes.wFont; + paragraph->u.text.wVSpace = attributes.wVSpace; + paragraph->u.text.wHSpace = attributes.wHSpace; + paragraph->u.text.wIndent = attributes.wIndent; + paragraph->u.text.lpszText = (char*)paragraph + sizeof(HLPFILE_PARAGRAPH); + strcpy(paragraph->u.text.lpszText, text); + + attributes.wVSpace = 0; + attributes.wHSpace = 0; + } + /* else: null text, keep on storing attributes */ + text += textsize; + + if (*format == 0xff) + { + format++; + break; + } + + WINE_TRACE("format=%02x\n", *format); + switch (*format) + { + case 0x20: + WINE_FIXME("NIY20\n"); + format += 5; + break; + + case 0x21: + WINE_FIXME("NIY21\n"); + format += 3; + break; + + case 0x80: + attributes.wFont = GET_USHORT(format, 1); + WINE_TRACE("Changing font to %d\n", attributes.wFont); + format += 3; + break; + + case 0x81: + attributes.wVSpace++; + format += 1; + break; + + case 0x82: + attributes.wVSpace++; + attributes.wIndent = 0; + format += 1; + break; + + case 0x83: + attributes.wIndent++; + format += 1; + break; + +#if 0 + case 0x84: + format += 3; + break; +#endif + + case 0x86: + case 0x87: + case 0x88: + { + BYTE pos = (*format - 0x86); + BYTE type = format[1]; + long size; + + format += 2; + size = fetch_long(&format); + + paragraph = HeapAlloc(GetProcessHeap(), 0, + sizeof(HLPFILE_PARAGRAPH) + textsize); + if (!paragraph) return FALSE; + *paragraphptr = paragraph; + paragraphptr = ¶graph->next; + + paragraph->next = NULL; + paragraph->link = attributes.link; + if (paragraph->link) paragraph->link->wRefCount++; + paragraph->cookie = para_bitmap; + paragraph->u.gfx.pos = pos; + switch (type) + { + case 0x22: + fetch_ushort(&format); /* hot spot */ + /* fall thru */ + case 0x03: + switch (GET_SHORT(format, 0)) + { + case 0: + HLPFILE_LoadGfxByIndex(hlpfile, GET_SHORT(format, 2), + paragraph); + break; + case 1: + WINE_FIXME("does it work ??? %x<%lu>#%u\n", + GET_SHORT(format, 0), + size, GET_SHORT(format, 2)); + HLPFILE_LoadGfxByAddr(hlpfile, format + 2, size - 4, + paragraph); + break; + default: + WINE_FIXME("??? %u\n", GET_SHORT(format, 0)); + break; + } + break; + case 0x05: + WINE_FIXME("Got an embedded element %s\n", format + 6); + break; + default: + WINE_FIXME("Got a type %d picture\n", type); + break; + } + if (attributes.wVSpace) paragraph->u.gfx.pos |= 0x8000; + + format += size; + } + break; + + case 0x89: + HLPFILE_FreeLink(attributes.link); + attributes.link = NULL; + format += 1; + break; + + case 0x8B: + case 0x8C: + WINE_FIXME("NIY non-break space/hyphen\n"); + format += 1; + break; + +#if 0 + case 0xA9: + format += 2; + break; +#endif + + case 0xC8: + case 0xCC: + WINE_TRACE("macro => %s\n", format + 3); + HLPFILE_FreeLink(attributes.link); + attributes.link = HLPFILE_AllocLink(hlp_link_macro, (const char*)format + 3, + 0, !(*format & 4), -1); + format += 3 + GET_USHORT(format, 1); + break; + + case 0xE0: + case 0xE1: + WINE_WARN("jump topic 1 => %u\n", GET_UINT(format, 1)); + format += 5; + break; + + case 0xE2: + case 0xE3: + case 0xE6: + case 0xE7: + HLPFILE_FreeLink(attributes.link); + attributes.link = HLPFILE_AllocLink((*format & 1) ? hlp_link_link : hlp_link_popup, + hlpfile->lpszPath, + GET_UINT(format, 1), + !(*format & 4), -1); + format += 5; + break; + + case 0xEA: + case 0xEB: + case 0xEE: + case 0xEF: + { + char* ptr = (char*) format + 8; + BYTE type = format[3]; + int wnd = -1; + char* str; + + if (type == 1) wnd = *ptr++; + if (type == 4 || type == 6) + { + str = ptr; + ptr += strlen(ptr) + 1; + } + else + str = hlpfile->lpszPath; + if (type == 6) + { + for (wnd = hlpfile->numWindows - 1; wnd >= 0; wnd--) + { + if (!strcmp(ptr, hlpfile->windows[wnd].name)) break; + } + if (wnd == -1) + WINE_WARN("Couldn't find window info for %s\n", ptr); + } + HLPFILE_FreeLink(attributes.link); + attributes.link = HLPFILE_AllocLink((*format & 4) ? hlp_link_link : hlp_link_popup, + str, GET_UINT(format, 4), + !(*format & 1), wnd); + } + format += 3 + GET_USHORT(format, 1); + break; + + default: + WINE_WARN("format %02x\n", *format); + format++; + } + } + } + if (text_end != (char*)buf + GET_UINT(buf, 0x10) + size) + HeapFree(GetProcessHeap(), 0, text_end - size); + return TRUE; +} + +/****************************************************************** + * HLPFILE_ReadFont + * + * + */ +static BOOL HLPFILE_ReadFont(HLPFILE* hlpfile) +{ + BYTE *ref, *end; + unsigned i, len, idx; + unsigned face_num, dscr_num, face_offset, dscr_offset; + BYTE flag, family; + + if (!HLPFILE_FindSubFile("|FONT", &ref, &end)) + { + WINE_WARN("no subfile FONT\n"); + hlpfile->numFonts = 0; + hlpfile->fonts = NULL; + return FALSE; + } + + ref += 9; + + face_num = GET_USHORT(ref, 0); + dscr_num = GET_USHORT(ref, 2); + face_offset = GET_USHORT(ref, 4); + dscr_offset = GET_USHORT(ref, 6); + + WINE_TRACE("Got NumFacenames=%u@%u NumDesc=%u@%u\n", + face_num, face_offset, dscr_num, dscr_offset); + + hlpfile->numFonts = dscr_num; + hlpfile->fonts = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_FONT) * dscr_num); + + len = (dscr_offset - face_offset) / face_num; +/* EPP for (i = face_offset; i < dscr_offset; i += len) */ +/* EPP WINE_FIXME("[%d]: %*s\n", i / len, len, ref + i); */ + for (i = 0; i < dscr_num; i++) + { + flag = ref[dscr_offset + i * 11 + 0]; + family = ref[dscr_offset + i * 11 + 2]; + + hlpfile->fonts[i].LogFont.lfHeight = -ref[dscr_offset + i * 11 + 1] / 2; + hlpfile->fonts[i].LogFont.lfWidth = 0; + hlpfile->fonts[i].LogFont.lfEscapement = 0; + hlpfile->fonts[i].LogFont.lfOrientation = 0; + hlpfile->fonts[i].LogFont.lfWeight = (flag & 1) ? 700 : 400; + hlpfile->fonts[i].LogFont.lfItalic = (flag & 2) ? TRUE : FALSE; + hlpfile->fonts[i].LogFont.lfUnderline = (flag & 4) ? TRUE : FALSE; + hlpfile->fonts[i].LogFont.lfStrikeOut = (flag & 8) ? TRUE : FALSE; + hlpfile->fonts[i].LogFont.lfCharSet = ANSI_CHARSET; + hlpfile->fonts[i].LogFont.lfOutPrecision = OUT_DEFAULT_PRECIS; + hlpfile->fonts[i].LogFont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + hlpfile->fonts[i].LogFont.lfQuality = DEFAULT_QUALITY; + hlpfile->fonts[i].LogFont.lfPitchAndFamily = DEFAULT_PITCH; + + switch (family) + { + case 0x01: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_MODERN; break; + case 0x02: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_ROMAN; break; + case 0x03: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_SWISS; break; + case 0x04: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_SCRIPT; break; + case 0x05: hlpfile->fonts[i].LogFont.lfPitchAndFamily |= FF_DECORATIVE; break; + default: WINE_FIXME("Unknown family %u\n", family); + } + idx = GET_USHORT(ref, dscr_offset + i * 11 + 3); + + if (idx < face_num) + { + memcpy(hlpfile->fonts[i].LogFont.lfFaceName, ref + face_offset + idx * len, min(len, LF_FACESIZE - 1)); + hlpfile->fonts[i].LogFont.lfFaceName[min(len, LF_FACESIZE - 1)] = '\0'; + } + else + { + WINE_FIXME("Too high face ref (%u/%u)\n", idx, face_num); + strcpy(hlpfile->fonts[i].LogFont.lfFaceName, "Helv"); + } + hlpfile->fonts[i].hFont = 0; + hlpfile->fonts[i].color = RGB(ref[dscr_offset + i * 11 + 5], + ref[dscr_offset + i * 11 + 6], + ref[dscr_offset + i * 11 + 7]); +#define X(b,s) ((flag & (1 << b)) ? "-"s: "") + WINE_TRACE("Font[%d]: flags=%02x%s%s%s%s%s%s pSize=%u family=%u face=%s[%u] color=%08x\n", + i, flag, + X(0, "bold"), + X(1, "italic"), + X(2, "underline"), + X(3, "strikeOut"), + X(4, "dblUnderline"), + X(5, "smallCaps"), + ref[dscr_offset + i * 11 + 1], + family, + hlpfile->fonts[i].LogFont.lfFaceName, idx, + GET_UINT(ref, dscr_offset + i * 11 + 5) & 0x00FFFFFF); + } + return TRUE; +} + +/*********************************************************************** + * + * HLPFILE_ReadFileToBuffer + */ +static BOOL HLPFILE_ReadFileToBuffer(HFILE hFile) +{ + BYTE header[16], dummy[1]; + UINT size; + + if (_hread(hFile, header, 16) != 16) {WINE_WARN("header\n"); return FALSE;}; + + /* sanity checks */ + if (GET_UINT(header, 0) != 0x00035F3F) + {WINE_WARN("wrong header\n"); return FALSE;}; + + size = GET_UINT(header, 12); + file_buffer = HeapAlloc(GetProcessHeap(), 0, size + 1); + if (!file_buffer) return FALSE; + + memcpy(file_buffer, header, 16); + if (_hread(hFile, file_buffer + 16, size - 16) != size - 16) + {WINE_WARN("filesize1\n"); return FALSE;}; + + if (_hread(hFile, dummy, 1) != 0) WINE_WARN("filesize2\n"); + + file_buffer[size] = '\0'; /* FIXME: was '0', sounds ackward to me */ + + return TRUE; +} + +/*********************************************************************** + * + * HLPFILE_FindSubFile + */ +static BOOL HLPFILE_FindSubFile(LPCSTR name, BYTE **subbuf, BYTE **subend) +{ + BYTE *root = file_buffer + GET_UINT(file_buffer, 4); + BYTE *end = file_buffer + GET_UINT(file_buffer, 12); + BYTE *ptr; + BYTE *bth; + + unsigned pgsize; + unsigned pglast; + unsigned nentries; + unsigned i, n; + + bth = root + 9; + + /* FIXME: this should be using the EnumBTree functions from this file */ + pgsize = GET_USHORT(bth, 4); + WINE_TRACE("%s => pgsize=%u #pg=%u rootpg=%u #lvl=%u\n", + name, pgsize, GET_USHORT(bth, 30), GET_USHORT(bth, 26), GET_USHORT(bth, 32)); + + ptr = bth + 38 + GET_USHORT(bth, 26) * pgsize; + + for (n = 1; n < GET_USHORT(bth, 32); n++) + { + nentries = GET_USHORT(ptr, 2); + pglast = GET_USHORT(ptr, 4); + WINE_TRACE("[%u]: #entries=%u next=%u\n", n, nentries, pglast); + + ptr += 6; + for (i = 0; i < nentries; i++) + { + char *str = (char*) ptr; + WINE_TRACE("<= %s\n", str); + if (strcmp(name, str) < 0) break; + ptr += strlen(str) + 1; + pglast = GET_USHORT(ptr, 0); + ptr += 2; + } + ptr = bth + 38 + pglast * pgsize; + } + + nentries = GET_USHORT(ptr, 2); + ptr += 8; + for (i = 0; i < nentries; i++) + { + char* fname = (char*)ptr; + ptr += strlen(fname) + 1; + WINE_TRACE("\\- %s\n", fname); + if (strcmp(fname, name) == 0) + { + *subbuf = file_buffer + GET_UINT(ptr, 0); + *subend = *subbuf + GET_UINT(*subbuf, 0); + if (file_buffer > *subbuf || *subbuf > *subend || *subend > end) + { + WINE_WARN("size mismatch\n"); + return FALSE; + } + return TRUE; + } + ptr += 4; + } + + return FALSE; +} + +/*********************************************************************** + * + * HLPFILE_SystemCommands + */ +static BOOL HLPFILE_SystemCommands(HLPFILE* hlpfile) +{ + BYTE *buf, *ptr, *end; + HLPFILE_MACRO *macro, **m; + LPSTR p; + unsigned short magic, minor, major, flags; + + hlpfile->lpszTitle = NULL; + + if (!HLPFILE_FindSubFile("|SYSTEM", &buf, &end)) return FALSE; + + magic = GET_USHORT(buf + 9, 0); + minor = GET_USHORT(buf + 9, 2); + major = GET_USHORT(buf + 9, 4); + /* gen date on 4 bytes */ + flags = GET_USHORT(buf + 9, 10); + WINE_TRACE("Got system header: magic=%04x version=%d.%d flags=%04x\n", + magic, major, minor, flags); + if (magic != 0x036C || major != 1) + {WINE_WARN("Wrong system header\n"); return FALSE;} + if (minor <= 16) {WINE_WARN("too old file format (NIY)\n"); return FALSE;} + if (flags & 8) {WINE_WARN("Unsupported yet page size\n"); return FALSE;} + + hlpfile->version = minor; + hlpfile->flags = flags; + + for (ptr = buf + 0x15; ptr + 4 <= end; ptr += GET_USHORT(ptr, 2) + 4) + { + char *str = (char*) ptr + 4; + switch (GET_USHORT(ptr, 0)) + { + case 1: + if (hlpfile->lpszTitle) {WINE_WARN("title\n"); break;} + hlpfile->lpszTitle = HeapAlloc(GetProcessHeap(), 0, strlen(str) + 1); + if (!hlpfile->lpszTitle) return FALSE; + lstrcpy(hlpfile->lpszTitle, str); + WINE_TRACE("Title: %s\n", hlpfile->lpszTitle); + break; + + case 2: + if (hlpfile->lpszCopyright) {WINE_WARN("copyright\n"); break;} + hlpfile->lpszCopyright = HeapAlloc(GetProcessHeap(), 0, strlen(str) + 1); + if (!hlpfile->lpszCopyright) return FALSE; + lstrcpy(hlpfile->lpszCopyright, str); + WINE_TRACE("Copyright: %s\n", hlpfile->lpszCopyright); + break; + + case 3: + if (GET_USHORT(ptr, 2) != 4) {WINE_WARN("system3\n");break;} + hlpfile->contents_start = GET_UINT(ptr, 4); + WINE_TRACE("Setting contents start at %08lx\n", hlpfile->contents_start); + break; + + case 4: + macro = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_MACRO) + lstrlen(str) + 1); + if (!macro) break; + p = (char*)macro + sizeof(HLPFILE_MACRO); + lstrcpy(p, str); + macro->lpszMacro = p; + macro->next = 0; + for (m = &hlpfile->first_macro; *m; m = &(*m)->next); + *m = macro; + break; + + case 6: + if (GET_USHORT(ptr, 2) != 90) {WINE_WARN("system6\n");break;} + + if (hlpfile->windows) + hlpfile->windows = HeapReAlloc(GetProcessHeap(), 0, hlpfile->windows, + sizeof(HLPFILE_WINDOWINFO) * ++hlpfile->numWindows); + else + hlpfile->windows = HeapAlloc(GetProcessHeap(), 0, + sizeof(HLPFILE_WINDOWINFO) * ++hlpfile->numWindows); + + if (hlpfile->windows) + { + unsigned flags = GET_USHORT(ptr, 4); + HLPFILE_WINDOWINFO* wi = &hlpfile->windows[hlpfile->numWindows - 1]; + + if (flags & 0x0001) strcpy(wi->type, &str[2]); + else wi->type[0] = '\0'; + if (flags & 0x0002) strcpy(wi->name, &str[12]); + else wi->name[0] = '\0'; + if (flags & 0x0004) strcpy(wi->caption, &str[23]); + else lstrcpynA(wi->caption, hlpfile->lpszTitle, sizeof(wi->caption)); + wi->origin.x = (flags & 0x0008) ? GET_USHORT(ptr, 76) : CW_USEDEFAULT; + wi->origin.y = (flags & 0x0010) ? GET_USHORT(ptr, 78) : CW_USEDEFAULT; + wi->size.cx = (flags & 0x0020) ? GET_USHORT(ptr, 80) : CW_USEDEFAULT; + wi->size.cy = (flags & 0x0040) ? GET_USHORT(ptr, 82) : CW_USEDEFAULT; + wi->style = (flags & 0x0080) ? GET_USHORT(ptr, 84) : SW_SHOW; + wi->win_style = WS_OVERLAPPEDWINDOW; + wi->sr_color = (flags & 0x0100) ? GET_UINT(ptr, 86) : 0xFFFFFF; + wi->nsr_color = (flags & 0x0200) ? GET_UINT(ptr, 90) : 0xFFFFFF; + WINE_TRACE("System-Window: flags=%c%c%c%c%c%c%c%c type=%s name=%s caption=%s (%d,%d)x(%d,%d)\n", + flags & 0x0001 ? 'T' : 't', + flags & 0x0002 ? 'N' : 'n', + flags & 0x0004 ? 'C' : 'c', + flags & 0x0008 ? 'X' : 'x', + flags & 0x0010 ? 'Y' : 'y', + flags & 0x0020 ? 'W' : 'w', + flags & 0x0040 ? 'H' : 'h', + flags & 0x0080 ? 'S' : 's', + wi->type, wi->name, wi->caption, wi->origin.x, wi->origin.y, + wi->size.cx, wi->size.cy); + } + break; + default: + WINE_WARN("Unsupported SystemRecord[%d]\n", GET_USHORT(ptr, 0)); + } + } + if (!hlpfile->lpszTitle) + hlpfile->lpszTitle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1); + return TRUE; +} + +/*********************************************************************** + * + * HLPFILE_UncompressedLZ77_Size + */ +static INT HLPFILE_UncompressedLZ77_Size(BYTE *ptr, BYTE *end) +{ + int i, newsize = 0; + + while (ptr < end) + { + int mask = *ptr++; + for (i = 0; i < 8 && ptr < end; i++, mask >>= 1) + { + if (mask & 1) + { + int code = GET_USHORT(ptr, 0); + int len = 3 + (code >> 12); + newsize += len; + ptr += 2; + } + else newsize++, ptr++; + } + } + + return newsize; +} + +/*********************************************************************** + * + * HLPFILE_UncompressLZ77 + */ +static BYTE *HLPFILE_UncompressLZ77(BYTE *ptr, BYTE *end, BYTE *newptr) +{ + int i; + + while (ptr < end) + { + int mask = *ptr++; + for (i = 0; i < 8 && ptr < end; i++, mask >>= 1) + { + if (mask & 1) + { + int code = GET_USHORT(ptr, 0); + int len = 3 + (code >> 12); + int offset = code & 0xfff; + /* + * We must copy byte-by-byte here. We cannot use memcpy nor + * memmove here. Just example: + * a[]={1,2,3,4,5,6,7,8,9,10} + * newptr=a+2; + * offset=1; + * We expect: + * {1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 11, 12} + */ + for (; len>0; len--, newptr++) *newptr = *(newptr-offset-1); + ptr += 2; + } + else *newptr++ = *ptr++; + } + } + + return newptr; +} + +/*********************************************************************** + * + * HLPFILE_UncompressLZ77_Phrases + */ +static BOOL HLPFILE_UncompressLZ77_Phrases(HLPFILE* hlpfile) +{ + UINT i, num, dec_size; + BYTE *buf, *end; + + if (!HLPFILE_FindSubFile("|Phrases", &buf, &end)) return FALSE; + + num = phrases.num = GET_USHORT(buf, 9); + if (buf + 2 * num + 0x13 >= end) {WINE_WARN("1a\n"); return FALSE;}; + + dec_size = HLPFILE_UncompressedLZ77_Size(buf + 0x13 + 2 * num, end); + + phrases.offsets = HeapAlloc(GetProcessHeap(), 0, sizeof(unsigned) * (num + 1)); + phrases.buffer = HeapAlloc(GetProcessHeap(), 0, dec_size); + if (!phrases.offsets || !phrases.buffer) return FALSE; + + for (i = 0; i <= num; i++) + phrases.offsets[i] = GET_USHORT(buf, 0x11 + 2 * i) - 2 * num - 2; + + HLPFILE_UncompressLZ77(buf + 0x13 + 2 * num, end, (BYTE*)phrases.buffer); + + hlpfile->hasPhrases = TRUE; + return TRUE; +} + +/*********************************************************************** + * + * HLPFILE_Uncompress_Phrases40 + */ +static BOOL HLPFILE_Uncompress_Phrases40(HLPFILE* hlpfile) +{ + UINT num, dec_size, cpr_size; + BYTE *buf_idx, *end_idx; + BYTE *buf_phs, *end_phs; + short i, n; + long* ptr, mask = 0; + unsigned short bc; + + if (!HLPFILE_FindSubFile("|PhrIndex", &buf_idx, &end_idx) || + !HLPFILE_FindSubFile("|PhrImage", &buf_phs, &end_phs)) return FALSE; + + ptr = (long*)(buf_idx + 9 + 28); + bc = GET_USHORT(buf_idx, 9 + 24) & 0x0F; + num = phrases.num = GET_USHORT(buf_idx, 9 + 4); + + WINE_TRACE("Index: Magic=%08x #entries=%u CpsdSize=%u PhrImgSize=%u\n" + "\tPhrImgCprsdSize=%u 0=%u bc=%x ukn=%x\n", + GET_UINT(buf_idx, 9 + 0), + GET_UINT(buf_idx, 9 + 4), + GET_UINT(buf_idx, 9 + 8), + GET_UINT(buf_idx, 9 + 12), + GET_UINT(buf_idx, 9 + 16), + GET_UINT(buf_idx, 9 + 20), + GET_USHORT(buf_idx, 9 + 24), + GET_USHORT(buf_idx, 9 + 26)); + + dec_size = GET_UINT(buf_idx, 9 + 12); + cpr_size = GET_UINT(buf_idx, 9 + 16); + + if (dec_size != cpr_size && + dec_size != HLPFILE_UncompressedLZ77_Size(buf_phs + 9, end_phs)) + { + WINE_WARN("size mismatch %u %u\n", + dec_size, HLPFILE_UncompressedLZ77_Size(buf_phs + 9, end_phs)); + dec_size = max(dec_size, HLPFILE_UncompressedLZ77_Size(buf_phs + 9, end_phs)); + } + + phrases.offsets = HeapAlloc(GetProcessHeap(), 0, sizeof(unsigned) * (num + 1)); + phrases.buffer = HeapAlloc(GetProcessHeap(), 0, dec_size); + if (!phrases.offsets || !phrases.buffer) return FALSE; + +#define getbit() (ptr += (mask < 0), mask = mask*2 + (mask<=0), (*ptr & mask) != 0) + + phrases.offsets[0] = 0; + for (i = 0; i < num; i++) + { + for (n = 1; getbit(); n += 1 << bc); + if (getbit()) n++; + if (bc > 1 && getbit()) n += 2; + if (bc > 2 && getbit()) n += 4; + if (bc > 3 && getbit()) n += 8; + if (bc > 4 && getbit()) n += 16; + phrases.offsets[i + 1] = phrases.offsets[i] + n; + } +#undef getbit + + if (dec_size == cpr_size) + memcpy(phrases.buffer, buf_phs + 9, dec_size); + else + HLPFILE_UncompressLZ77(buf_phs + 9, end_phs, (BYTE*)phrases.buffer); + + hlpfile->hasPhrases = FALSE; + return TRUE; +} + +/*********************************************************************** + * + * HLPFILE_Uncompress_Topic + */ +static BOOL HLPFILE_Uncompress_Topic(HLPFILE* hlpfile) +{ + BYTE *buf, *ptr, *end, *newptr; + int i, newsize = 0; + + if (!HLPFILE_FindSubFile("|TOPIC", &buf, &end)) + {WINE_WARN("topic0\n"); return FALSE;} + + switch (hlpfile->flags & (8|4)) + { + case 8: + WINE_FIXME("Unsupported format\n"); + return FALSE; + case 4: + buf += 9; + topic.wMapLen = (end - buf - 1) / 0x1000 + 1; + + for (i = 0; i < topic.wMapLen; i++) + { + ptr = buf + i * 0x1000; + + /* I don't know why, it's necessary for printman.hlp */ + if (ptr + 0x44 > end) ptr = end - 0x44; + + newsize += HLPFILE_UncompressedLZ77_Size(ptr + 0xc, min(end, ptr + 0x1000)); + } + + topic.map = HeapAlloc(GetProcessHeap(), 0, + topic.wMapLen * sizeof(topic.map[0]) + newsize); + if (!topic.map) return FALSE; + newptr = (BYTE*)(topic.map + topic.wMapLen); + topic.end = newptr + newsize; + + for (i = 0; i < topic.wMapLen; i++) + { + ptr = buf + i * 0x1000; + if (ptr + 0x44 > end) ptr = end - 0x44; + + topic.map[i] = newptr; + newptr = HLPFILE_UncompressLZ77(ptr + 0xc, min(end, ptr + 0x1000), newptr); + } + break; + case 0: + /* basically, we need to copy the 0x1000 byte pages (removing the first 0x0C) in + * one single are in memory + */ +#define DST_LEN (0x1000 - 0x0C) + buf += 9; + newsize = end - buf; + /* number of destination pages */ + topic.wMapLen = (newsize - 1) / DST_LEN + 1; + topic.map = HeapAlloc(GetProcessHeap(), 0, + topic.wMapLen * (sizeof(topic.map[0]) + DST_LEN)); + if (!topic.map) return FALSE; + newptr = (BYTE*)(topic.map + topic.wMapLen); + topic.end = newptr + newsize; + + for (i = 0; i < topic.wMapLen; i++) + { + topic.map[i] = newptr + i * DST_LEN; + memcpy(topic.map[i], buf + i * 0x1000 + 0x0C, DST_LEN); + } +#undef DST_LEN + break; + } + return TRUE; +} + +/*********************************************************************** + * + * HLPFILE_Uncompress2 + */ + +static void HLPFILE_Uncompress2(const BYTE *ptr, const BYTE *end, BYTE *newptr, const BYTE *newend) +{ + BYTE *phptr, *phend; + UINT code; + UINT index; + + while (ptr < end && newptr < newend) + { + if (!*ptr || *ptr >= 0x10) + *newptr++ = *ptr++; + else + { + code = 0x100 * ptr[0] + ptr[1]; + index = (code - 0x100) / 2; + + phptr = (BYTE*)phrases.buffer + phrases.offsets[index]; + phend = (BYTE*)phrases.buffer + phrases.offsets[index + 1]; + + if (newptr + (phend - phptr) > newend) + { + WINE_FIXME("buffer overflow %p > %p for %d bytes\n", + newptr, newend, phend - phptr); + return; + } + memcpy(newptr, phptr, phend - phptr); + newptr += phend - phptr; + if (code & 1) *newptr++ = ' '; + + ptr += 2; + } + } + if (newptr > newend) WINE_FIXME("buffer overflow %p > %p\n", newptr, newend); +} + +/****************************************************************** + * HLPFILE_Uncompress3 + * + * + */ +static BOOL HLPFILE_Uncompress3(char* dst, const char* dst_end, + const BYTE* src, const BYTE* src_end) +{ + int idx, len; + + for (; src < src_end; src++) + { + if ((*src & 1) == 0) + { + idx = *src / 2; + if (idx > phrases.num) + { + WINE_ERR("index in phrases %d/%d\n", idx, phrases.num); + len = 0; + } + else + { + len = phrases.offsets[idx + 1] - phrases.offsets[idx]; + if (dst + len <= dst_end) + memcpy(dst, &phrases.buffer[phrases.offsets[idx]], len); + } + } + else if ((*src & 0x03) == 0x01) + { + idx = (*src + 1) * 64; + idx += *++src; + if (idx > phrases.num) + { + WINE_ERR("index in phrases %d/%d\n", idx, phrases.num); + len = 0; + } + else + { + len = phrases.offsets[idx + 1] - phrases.offsets[idx]; + if (dst + len <= dst_end) + memcpy(dst, &phrases.buffer[phrases.offsets[idx]], len); + } + } + else if ((*src & 0x07) == 0x03) + { + len = (*src / 8) + 1; + if (dst + len <= dst_end) + memcpy(dst, src + 1, len); + src += len; + } + else + { + len = (*src / 16) + 1; + if (dst + len <= dst_end) + memset(dst, ((*src & 0x0F) == 0x07) ? ' ' : 0, len); + } + dst += len; + } + + if (dst > dst_end) WINE_ERR("buffer overflow (%p > %p)\n", dst, dst_end); + return TRUE; +} + +/****************************************************************** + * HLPFILE_UncompressRLE + * + * + */ +static void HLPFILE_UncompressRLE(const BYTE* src, const BYTE* end, BYTE** dst, unsigned dstsz) +{ + BYTE ch; + BYTE* sdst = *dst + dstsz; + + while (src < end) + { + ch = *src++; + if (ch & 0x80) + { + ch &= 0x7F; + if ((*dst) + ch <= sdst) + memcpy(*dst, src, ch); + src += ch; + } + else + { + if ((*dst) + ch <= sdst) + memset(*dst, (char)*src, ch); + src++; + } + *dst += ch; + } + if (*dst != sdst) + WINE_WARN("Buffer X-flow: d(%u) instead of d(%u)\n", + *dst - (sdst - dstsz), dstsz); +} + +/****************************************************************** + * HLPFILE_EnumBTreeLeaves + * + * + */ +static void HLPFILE_EnumBTreeLeaves(const BYTE* buf, const BYTE* end, unsigned (*fn)(const BYTE*, void*), void* user) +{ + unsigned psize, pnext; + unsigned num, nlvl; + const BYTE* ptr; + + num = GET_UINT(buf, 9 + 34); + psize = GET_USHORT(buf, 9 + 4); + nlvl = GET_USHORT(buf, 9 + 32); + pnext = GET_USHORT(buf, 9 + 26); + + WINE_TRACE("BTree: #entries=%u pagSize=%u #levels=%u #pages=%u root=%u struct%16s\n", + num, psize, nlvl, GET_USHORT(buf, 9 + 30), pnext, buf + 9 + 6); + if (!num) return; + + while (--nlvl > 0) + { + ptr = (buf + 9 + 38) + pnext * psize; + WINE_TRACE("BTree: (index[%u]) unused=%u #entries=%u <%u\n", + pnext, GET_USHORT(ptr, 0), GET_USHORT(ptr, 2), GET_USHORT(ptr, 4)); + pnext = GET_USHORT(ptr, 4); + } + while (pnext != 0xFFFF) + { + const BYTE* node_page; + unsigned short limit; + + node_page = ptr = (buf + 9 + 38) + pnext * psize; + limit = GET_USHORT(ptr, 2); + WINE_TRACE("BTree: (leaf [%u]) unused=%u #entries=%u <%u >%u\n", + pnext, GET_USHORT(ptr, 0), limit, GET_USHORT(ptr, 4), GET_USHORT(ptr, 6)); + ptr += 8; + while (limit--) + ptr += (fn)(ptr, user); + pnext = GET_USHORT(node_page, 6); + } +} + +struct myfncb { + HLPFILE* hlpfile; + int i; +}; + +static unsigned myfn(const BYTE* ptr, void* user) +{ + struct myfncb* m = user; + + m->hlpfile->Context[m->i].lHash = GET_UINT(ptr, 0); + m->hlpfile->Context[m->i].offset = GET_UINT(ptr, 4); + m->i++; + return 8; +} + +/*********************************************************************** + * + * HLPFILE_GetContext + */ +static BOOL HLPFILE_GetContext(HLPFILE *hlpfile) +{ + BYTE *cbuf, *cend; + struct myfncb m; + unsigned clen; + + if (!HLPFILE_FindSubFile("|CONTEXT", &cbuf, &cend)) {WINE_WARN("context0\n"); return FALSE;} + + clen = GET_UINT(cbuf, 0x2b); + hlpfile->Context = HeapAlloc(GetProcessHeap(), 0, clen * sizeof(HLPFILE_CONTEXT)); + if (!hlpfile->Context) return FALSE; + hlpfile->wContextLen = clen; + + m.hlpfile = hlpfile; + m.i = 0; + HLPFILE_EnumBTreeLeaves(cbuf, cend, myfn, &m); + + return TRUE; +} + +/*********************************************************************** + * + * HLPFILE_GetMap + */ +static BOOL HLPFILE_GetMap(HLPFILE *hlpfile) +{ + BYTE *cbuf, *cend; + unsigned entries, i; + + if (!HLPFILE_FindSubFile("|CTXOMAP", &cbuf, &cend)) {WINE_WARN("no map section\n"); return FALSE;} + + entries = GET_USHORT(cbuf, 9); + hlpfile->Map = HeapAlloc(GetProcessHeap(), 0, entries * sizeof(HLPFILE_MAP)); + if (!hlpfile->Map) return FALSE; + hlpfile->wMapLen = entries; + for (i = 0; i < entries; i++) + { + hlpfile->Map[i].lMap = GET_UINT(cbuf+11,i*8); + hlpfile->Map[i].offset = GET_UINT(cbuf+11,i*8+4); + } + return TRUE; +} + +/****************************************************************** + * HLPFILE_DeleteLink + * + * + */ +void HLPFILE_FreeLink(HLPFILE_LINK* link) +{ + if (link && !--link->wRefCount) + HeapFree(GetProcessHeap(), 0, link); +} + +/*********************************************************************** + * + * HLPFILE_DeleteParagraph + */ +static void HLPFILE_DeleteParagraph(HLPFILE_PARAGRAPH* paragraph) +{ + HLPFILE_PARAGRAPH* next; + + while (paragraph) + { + next = paragraph->next; + + if (paragraph->cookie == para_metafile) + DeleteMetaFile(paragraph->u.gfx.u.mfp.hMF); + + HLPFILE_FreeLink(paragraph->link); + + HeapFree(GetProcessHeap(), 0, paragraph); + paragraph = next; + } +} + +/*********************************************************************** + * + * DeleteMacro + */ +static void HLPFILE_DeleteMacro(HLPFILE_MACRO* macro) +{ + HLPFILE_MACRO* next; + + while (macro) + { + next = macro->next; + HeapFree(GetProcessHeap(), 0, macro); + macro = next; + } +} + +/*********************************************************************** + * + * DeletePage + */ +static void HLPFILE_DeletePage(HLPFILE_PAGE* page) +{ + HLPFILE_PAGE* next; + + while (page) + { + next = page->next; + HLPFILE_DeleteParagraph(page->first_paragraph); + HLPFILE_DeleteMacro(page->first_macro); + HeapFree(GetProcessHeap(), 0, page); + page = next; + } +} + +/*********************************************************************** + * + * HLPFILE_FreeHlpFile + */ +void HLPFILE_FreeHlpFile(HLPFILE* hlpfile) +{ + unsigned i; + + if (!hlpfile || --hlpfile->wRefCount > 0) return; + + if (hlpfile->next) hlpfile->next->prev = hlpfile->prev; + if (hlpfile->prev) hlpfile->prev->next = hlpfile->next; + else first_hlpfile = hlpfile->next; + + if (hlpfile->numFonts) + { + for (i = 0; i < hlpfile->numFonts; i++) + { + DeleteObject(hlpfile->fonts[i].hFont); + } + HeapFree(GetProcessHeap(), 0, hlpfile->fonts); + } + + if (hlpfile->numBmps) + { + for (i = 0; i < hlpfile->numBmps; i++) + { + DeleteObject(hlpfile->bmps[i]); + } + HeapFree(GetProcessHeap(), 0, hlpfile->bmps); + } + + HLPFILE_DeletePage(hlpfile->first_page); + HLPFILE_DeleteMacro(hlpfile->first_macro); + + if (hlpfile->numWindows) HeapFree(GetProcessHeap(), 0, hlpfile->windows); + HeapFree(GetProcessHeap(), 0, hlpfile->Context); + HeapFree(GetProcessHeap(), 0, hlpfile->Map); + HeapFree(GetProcessHeap(), 0, hlpfile->lpszTitle); + HeapFree(GetProcessHeap(), 0, hlpfile->lpszCopyright); + HeapFree(GetProcessHeap(), 0, hlpfile); +} diff --git a/reactos/base/applications/winhelp/hlpfile.h b/reactos/base/applications/winhelp/hlpfile.h new file mode 100644 index 00000000000..4d62cdd22ed --- /dev/null +++ b/reactos/base/applications/winhelp/hlpfile.h @@ -0,0 +1,163 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * 2002 Eric Pouech + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +struct tagHelpFile; + +typedef struct +{ + char type[10]; + char name[9]; + char caption[51]; + POINT origin; + SIZE size; + int style; + DWORD win_style; + COLORREF sr_color; /* color for scrollable region */ + COLORREF nsr_color; /* color for non scrollable region */ +} HLPFILE_WINDOWINFO; + +typedef struct +{ + enum {hlp_link_link, hlp_link_popup, hlp_link_macro} cookie; + LPCSTR lpszString; /* name of the file to for the link (NULL if same file) */ + LONG lHash; /* topic index */ + unsigned bClrChange : 1, /* true if the link is green & underlined */ + wRefCount; /* number of internal references to this object */ + unsigned window; /* window number for displaying the link (-1 is current) */ +} HLPFILE_LINK; + +enum para_type {para_normal_text, para_debug_text, para_bitmap, para_metafile}; + +typedef struct tagHlpFileParagraph +{ + enum para_type cookie; + + union + { + struct + { + LPSTR lpszText; + unsigned wFont; + unsigned wIndent; + unsigned wHSpace; + unsigned wVSpace; + } text; + struct + { + unsigned pos; /* 0: center, 1: left, 2: right */ + union + { + struct + { + HBITMAP hBitmap; + } bmp; + METAFILEPICT mfp; + } u; + } gfx; /* for bitmaps and metafiles */ + } u; + + HLPFILE_LINK* link; + + struct tagHlpFileParagraph* next; +} HLPFILE_PARAGRAPH; + +typedef struct tagHlpFileMacro +{ + LPCSTR lpszMacro; + struct tagHlpFileMacro* next; +} HLPFILE_MACRO; + +typedef struct tagHlpFilePage +{ + LPSTR lpszTitle; + HLPFILE_PARAGRAPH* first_paragraph; + HLPFILE_MACRO* first_macro; + + unsigned wNumber; + unsigned offset; + struct tagHlpFilePage* next; + struct tagHlpFilePage* prev; + + DWORD browse_bwd; + DWORD browse_fwd; + + struct tagHlpFileFile* file; +} HLPFILE_PAGE; + +typedef struct +{ + LONG lHash; + unsigned long offset; +} HLPFILE_CONTEXT; + +typedef struct +{ + LONG lMap; + unsigned long offset; +} HLPFILE_MAP; + +typedef struct +{ + LOGFONT LogFont; + HFONT hFont; + COLORREF color; +} HLPFILE_FONT; + +typedef struct tagHlpFileFile +{ + LPSTR lpszPath; + LPSTR lpszTitle; + LPSTR lpszCopyright; + HLPFILE_PAGE* first_page; + HLPFILE_MACRO* first_macro; + unsigned wContextLen; + HLPFILE_CONTEXT* Context; + unsigned wMapLen; + HLPFILE_MAP* Map; + unsigned long contents_start; + + struct tagHlpFileFile* prev; + struct tagHlpFileFile* next; + + unsigned wRefCount; + + unsigned short version; + unsigned short flags; + unsigned hasPhrases; /* Phrases or PhrIndex/PhrImage */ + + unsigned numBmps; + HBITMAP* bmps; + + unsigned numFonts; + HLPFILE_FONT* fonts; + + unsigned numWindows; + HLPFILE_WINDOWINFO* windows; +} HLPFILE; + +HLPFILE* HLPFILE_ReadHlpFile(LPCSTR lpszPath); +HLPFILE_PAGE* HLPFILE_Contents(HLPFILE* hlpfile); +HLPFILE_PAGE* HLPFILE_PageByHash(HLPFILE* hlpfile, LONG lHash); +HLPFILE_PAGE* HLPFILE_PageByMap(HLPFILE* hlpfile, LONG lMap); +HLPFILE_PAGE* HLPFILE_PageByOffset(HLPFILE* hlpfile, LONG offset); +LONG HLPFILE_Hash(LPCSTR lpszContext); +void HLPFILE_FreeLink(HLPFILE_LINK* link); +void HLPFILE_FreeHlpFile(HLPFILE*); diff --git a/reactos/base/applications/winhelp/lex.yy.c b/reactos/base/applications/winhelp/lex.yy.c new file mode 100644 index 00000000000..9b34d385b83 --- /dev/null +++ b/reactos/base/applications/winhelp/lex.yy.c @@ -0,0 +1,1841 @@ +/* A lexical scanner generated by flex */ + +/* Scanner skeleton version: + * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.91 96/09/10 16:58:48 vern Exp $ + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 + +#include + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include +#include + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + +typedef unsigned char YY_CHAR; +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +typedef int yy_state_type; +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 14 +#define YY_END_OF_BUFFER 15 +static yyconst short int yy_accept[28] = + { 0, + 0, 0, 0, 0, 15, 13, 14, 12, 5, 6, + 13, 1, 1, 3, 4, 10, 8, 9, 10, 7, + 1, 1, 0, 3, 11, 2, 0 + } ; + +static yyconst int yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 3, 1, 4, 1, 1, 1, 1, 5, 1, + 1, 1, 6, 1, 6, 1, 1, 7, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 1, 1, 1, + 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 10, 9, 9, + 1, 11, 1, 1, 12, 13, 14, 14, 14, 14, + + 14, 14, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, + 9, 9, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst int yy_meta[15] = + { 0, + 1, 2, 1, 1, 1, 1, 3, 3, 4, 5, + 1, 4, 1, 6 + } ; + +static yyconst short int yy_base[33] = + { 0, + 0, 0, 13, 25, 25, 62, 62, 62, 62, 62, + 12, 13, 14, 0, 62, 62, 62, 62, 0, 62, + 6, 24, 0, 0, 62, 0, 62, 38, 42, 45, + 51, 55 + } ; + +static yyconst short int yy_def[33] = + { 0, + 27, 1, 28, 28, 27, 27, 27, 27, 27, 27, + 27, 29, 27, 30, 27, 27, 27, 27, 31, 27, + 29, 27, 32, 30, 27, 32, 0, 27, 27, 27, + 27, 27 + } ; + +static yyconst short int yy_nxt[77] = + { 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, + 6, 6, 15, 14, 7, 23, 17, 18, 21, 22, + 22, 22, 23, 19, 27, 20, 7, 27, 17, 18, + 22, 22, 27, 27, 27, 19, 27, 20, 16, 16, + 16, 16, 16, 16, 22, 27, 22, 24, 24, 24, + 24, 25, 27, 25, 25, 25, 25, 26, 27, 27, + 26, 5, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27 + } ; + +static yyconst short int yy_chk[77] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 21, 3, 3, 11, 11, + 13, 13, 12, 3, 5, 3, 4, 0, 4, 4, + 22, 22, 0, 0, 0, 4, 0, 4, 28, 28, + 28, 28, 28, 28, 29, 0, 29, 30, 30, 30, + 30, 31, 0, 31, 31, 31, 31, 32, 0, 0, + 32, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +#define INITIAL 0 +#line 2 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Eric Pouech + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +#define YY_NO_UNPUT 1 +#define quote 1 + +#line 26 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +#include +#include "macro.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winhelp); + +static LPCSTR macroptr; +static LPSTR strptr; +static int quote_stack[32]; +static int quote_stk_idx = 0; +struct lexret yylval; + +#define YY_INPUT(buf,result,max_size)\ + if ((result = *macroptr ? 1 : 0)) buf[0] = *macroptr++; + +#line 427 "lex.yy.c" + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YY_PROTO(( yyconst char * )); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + +#line 43 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" + + +#line 581 "lex.yy.c" + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 28 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 62 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + +do_action: /* This label is used only to access EOF actions. */ + + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 45 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +yylval.integer = strtol(yytext, NULL, 10); return INTEGER; + YY_BREAK +case 2: +YY_RULE_SETUP +#line 46 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +yylval.integer = strtol(yytext, NULL, 16); return INTEGER; + YY_BREAK +case 3: +YY_RULE_SETUP +#line 48 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +return MACRO_Lookup(yytext, &yylval); + YY_BREAK +case 4: +#line 51 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +case 5: +#line 52 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +case 6: +#line 53 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +case 7: +#line 54 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +case 8: +#line 55 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +case 9: +YY_RULE_SETUP +#line 55 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +{ + if (quote_stk_idx == 0 || + (yytext[0] == '\"' && quote_stack[quote_stk_idx - 1] != '\"') || + (yytext[0] == '`')) + { + /* opening a new one */ + if (quote_stk_idx == 0) + { + strptr = HeapAlloc(GetProcessHeap(), 0, strlen(macroptr) + 1); + yylval.string = strptr; + BEGIN(quote); + } + else *strptr++ = yytext[0]; + quote_stack[quote_stk_idx++] = yytext[0]; + assert(quote_stk_idx < sizeof(quote_stack) / sizeof(quote_stack[0])); + } + else + { + if (yytext[0] == '`') assert(0); + /* close the current quote */ + if (--quote_stk_idx == 0) + { + BEGIN INITIAL; + *strptr++ = '\0'; + return STRING; + } + else *strptr++ = yytext[0]; + } +} + YY_BREAK +case 10: +YY_RULE_SETUP +#line 85 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +*strptr++ = yytext[0]; + YY_BREAK +case 11: +YY_RULE_SETUP +#line 86 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +*strptr++ = yytext[1]; + YY_BREAK +case YY_STATE_EOF(quote): +#line 87 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +return 0; + YY_BREAK +case 12: +YY_RULE_SETUP +#line 89 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" + + YY_BREAK +case 13: +YY_RULE_SETUP +#line 90 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +return yytext[0]; + YY_BREAK +case 14: +YY_RULE_SETUP +#line 91 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" +ECHO; + YY_BREAK +#line 751 "lex.yy.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer() + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state() + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 28 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif + { + register int yy_is_jam; + register char *yy_cp = yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 28 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 27); + + return yy_is_jam ? 0 : yy_current_state; + } + + +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ + + +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + + + return c; + } + + +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + +#ifndef YY_ALWAYS_INTERACTIVE +#ifndef YY_NEVER_INTERACTIVE +extern int isatty YY_PROTO(( int )); +#endif +#endif + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif + } + + +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + + { + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } + + +#ifndef YY_NO_SCAN_BUFFER +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +#endif + + +#ifndef YY_NO_SCAN_STRING +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +#else +YY_BUFFER_STATE yy_scan_string( yy_str ) +yyconst char *yy_str; +#endif + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; + + return yy_scan_bytes( yy_str, len ); + } +#endif + + +#ifndef YY_NO_SCAN_BYTES +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +#endif + + +#ifndef YY_NO_PUSH_STATE +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +static void yy_pop_state() + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +static int yy_top_state() + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef yytext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + +#ifdef YY_NEED_STRLEN +#ifdef YY_USE_PROTOS +static int yy_flex_strlen( yyconst char *s ) +#else +static int yy_flex_strlen( s ) +yyconst char *s; +#endif + { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + free( ptr ); + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif +#line 91 "D:\\ReactOS\\trunk\\reactos\\base\\applications\\winhelp\\macro.lex.l" + + +#if 0 +/* all code for testing macros */ +#include "winhelp.h" +static CHAR szTestMacro[256]; + +static LRESULT CALLBACK MACRO_TestDialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_COMMAND && wParam == IDOK) + { + GetDlgItemText(hDlg, 99, szTestMacro, sizeof(szTestMacro)); + EndDialog(hDlg, IDOK); + return TRUE; + } + return FALSE; +} + +void macro_test(void) +{ + WNDPROC lpfnDlg = MakeProcInstance(MACRO_TestDialogProc, Globals.hInstance); + DialogBox(Globals.hInstance, STRING_DIALOG_TEST, Globals.active_win->hMainWnd, (DLGPROC)lpfnDlg); + FreeProcInstance(lpfnDlg); + macro = szTestMacro; +} +#endif + +/* small helper function for debug messages */ +static const char* ts(int t) +{ + static char c[2] = {0,0}; + + switch (t) + { + case EMPTY: return "EMPTY"; + case VOID_FUNCTION: return "VOID_FUNCTION"; + case BOOL_FUNCTION: return "BOOL_FUNCTION"; + case INTEGER: return "INTEGER"; + case STRING: return "STRING"; + case IDENTIFIER: return "IDENTIFIER"; + default: c[0] = (char)t; return c; + } +} + +static int MACRO_CallBoolFunc(FARPROC fn, const char* args, void** ret); + +/****************************************************************** + * MACRO_CheckArgs + * + * checks number of arguments against prototype, and stores arguments on + * stack pa for later call + * returns -1 on error, otherwise the number of pushed parameters + */ +static int MACRO_CheckArgs(void* pa[], unsigned max, const char* args) +{ + int t; + int len = 0, idx = 0; + + WINE_TRACE("Checking %s\n", args); + + if (yylex() != '(') {WINE_WARN("missing (\n");return -1;} + + if (*args) + { + len = strlen(args); + for (;;) + { + t = yylex(); + WINE_TRACE("Got %s <=> %c\n", ts(t), *args); + + switch (*args) + { + case 'S': + if (t != STRING) + {WINE_WARN("missing S\n");return -1;} + pa[idx] = (void*)yylval.string; + break; + case 'U': + case 'I': + if (t != INTEGER) + {WINE_WARN("missing U\n");return -1;} + pa[idx] = (void*)yylval.integer; + break; + case 'B': + if (t != BOOL_FUNCTION) + {WINE_WARN("missing B\n");return -1;} + if (MACRO_CallBoolFunc(yylval.function, yylval.proto, &pa[idx]) == 0) + return -1; + break; + default: + WINE_WARN("unexpected %s while args is %c\n", ts(t), *args); + return -1; + } + idx++; + if (*++args == '\0') break; + t = yylex(); + if (t == ')') goto CheckArgs_end; + if (t != ',') {WINE_WARN("missing ,\n");return -1;} + if (idx >= max) {WINE_FIXME("stack overflow (%d)\n", max);return -1;} + } + } + if (yylex() != ')') {WINE_WARN("missing )\n");return -1;} + +CheckArgs_end: + while (len > idx) pa[--len] = NULL; + return idx; +} + +/****************************************************************** + * MACRO_CallBoolFunc + * + * Invokes boolean function fn, which arguments are defined by args + * stores bool result into ret + */ +static int MACRO_CallBoolFunc(FARPROC fn, const char* args, void** ret) +{ + void* pa[2]; + int idx = MACRO_CheckArgs(pa, sizeof(pa)/sizeof(pa[0]), args); + + if (idx < 0) return 0; + if (!fn) return 1; + + WINE_TRACE("calling with %u pmts\n", idx); + + switch (strlen(args)) + { + case 0: *ret = (void*)(fn)(); break; + case 1: *ret = (void*)(fn)(pa[0]); break; + default: WINE_FIXME("NIY\n"); + } + + return 1; +} + +/****************************************************************** + * MACRO_CallVoidFunc + * + * + */ +static int MACRO_CallVoidFunc(FARPROC fn, const char* args) +{ + void* pa[6]; + int idx = MACRO_CheckArgs(pa, sizeof(pa)/sizeof(pa[0]), args); + + if (idx < 0) return 0; + if (!fn) return 1; + + WINE_TRACE("calling %p with %u pmts\n", fn, idx); + + switch (strlen(args)) + { + case 0: (fn)(); break; + case 1: (fn)(pa[0]); break; + case 2: (fn)(pa[0],pa[1]); break; + case 3: (fn)(pa[0],pa[1],pa[2]); break; + case 4: (fn)(pa[0],pa[1],pa[2],pa[3]); break; + case 5: (fn)(pa[0],pa[1],pa[2],pa[3],pa[4]); break; + case 6: (fn)(pa[0],pa[1],pa[2],pa[3],pa[4],pa[5]); break; + default: WINE_FIXME("NIY\n"); + } + + return 1; +} + +BOOL MACRO_ExecuteMacro(LPCSTR macro) +{ + int t; + + //WINE_TRACE("%s\n", wine_dbgstr_a(macro)); + + macroptr = macro; + + while ((t = yylex()) != EMPTY) + { + switch (t) + { + case VOID_FUNCTION: + WINE_TRACE("got type void func(%s)\n", yylval.proto); + MACRO_CallVoidFunc(yylval.function, yylval.proto); + break; + case BOOL_FUNCTION: + WINE_WARN("got type bool func(%s)\n", yylval.proto); + break; + default: + WINE_WARN("got unexpected type %s\n", ts(t)); + return 0; + } + switch (t = yylex()) + { + case EMPTY: return 1; + case ';': break; + default: return 0; + } + } + + HeapFree(GetProcessHeap(), 0, strptr); + strptr = NULL; + quote_stk_idx = 0; + + return 1; +} + +#ifndef yywrap +int yywrap(void) { return 1; } +#endif diff --git a/reactos/base/applications/winhelp/macro.c b/reactos/base/applications/winhelp/macro.c new file mode 100644 index 00000000000..803b5bba935 --- /dev/null +++ b/reactos/base/applications/winhelp/macro.c @@ -0,0 +1,928 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Eric Pouech + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define WIN32_LEAN_AND_MEAN + +#include + +#include "windows.h" +#include "commdlg.h" +#include "winhelp.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winhelp); + +/**************************************************/ +/* Macro table */ +/**************************************************/ +struct MacroDesc { + const char* name; + const char* alias; + BOOL isBool; + const char* arguments; + FARPROC fn; +}; + +/* types: + * U: 32 bit unsigned int + * I: 32 bit signed int + * S: string + * v: unknown (32 bit entity) + */ + +static struct MacroDesc MACRO_Builtins[] = { + {"About", NULL, 0, "", (FARPROC)MACRO_About}, + {"AddAccelerator", "AA", 0, "UUS", (FARPROC)MACRO_AddAccelerator}, + {"ALink", "AL", 0, "SUS", (FARPROC)MACRO_ALink}, + {"Annotate", NULL, 0, "", (FARPROC)MACRO_Annotate}, + {"AppendItem", NULL, 0, "SSSS", (FARPROC)MACRO_AppendItem}, + {"Back", NULL, 0, "", (FARPROC)MACRO_Back}, + {"BackFlush", "BF", 0, "", (FARPROC)MACRO_BackFlush}, + {"BookmarkDefine", NULL, 0, "", (FARPROC)MACRO_BookmarkDefine}, + {"BookmarkMore", NULL, 0, "", (FARPROC)MACRO_BookmarkMore}, + {"BrowseButtons", NULL, 0, "", (FARPROC)MACRO_BrowseButtons}, + {"ChangeButtonBinding", "CBB",0, "SS", (FARPROC)MACRO_ChangeButtonBinding}, + {"ChangeEnable", "CE", 0, "SS", (FARPROC)MACRO_ChangeEnable}, + {"ChangeItemBinding", "CIB",0, "SS", (FARPROC)MACRO_ChangeItemBinding}, + {"CheckItem", "CI", 0, "S", (FARPROC)MACRO_CheckItem}, + {"CloseSecondarys", "CS", 0, "", (FARPROC)MACRO_CloseSecondarys}, + {"CloseWindow", "CW", 0, "S", (FARPROC)MACRO_CloseWindow}, + {"Compare", NULL, 0, "S", (FARPROC)MACRO_Compare}, + {"Contents", NULL, 0, "", (FARPROC)MACRO_Contents}, + {"ControlPanel", NULL, 0, "SSU", (FARPROC)MACRO_ControlPanel}, + {"CopyDialog", NULL, 0, "", (FARPROC)MACRO_CopyDialog}, + {"CopyTopic", "CT", 0, "", (FARPROC)MACRO_CopyTopic}, + {"CreateButton", "CB", 0, "SSS", (FARPROC)MACRO_CreateButton}, + {"DeleteItem", NULL, 0, "S", (FARPROC)MACRO_DeleteItem}, + {"DeleteMark", NULL, 0, "S", (FARPROC)MACRO_DeleteMark}, + {"DestroyButton", NULL, 0, "S", (FARPROC)MACRO_DestroyButton}, + {"DisableButton", "DB", 0, "S", (FARPROC)MACRO_DisableButton}, + {"DisableItem", "DI", 0, "S", (FARPROC)MACRO_DisableItem}, + {"EnableButton", "EB", 0, "S", (FARPROC)MACRO_EnableButton}, + {"EnableItem", "EI", 0, "S", (FARPROC)MACRO_EnableItem}, + {"EndMPrint", NULL, 0, "", (FARPROC)MACRO_EndMPrint}, + {"ExecFile", "EF", 0, "SSUS", (FARPROC)MACRO_ExecFile}, + {"ExecProgram", "EP", 0, "SU", (FARPROC)MACRO_ExecProgram}, + {"Exit", NULL, 0, "", (FARPROC)MACRO_Exit}, + {"ExtAbleItem", NULL, 0, "SU", (FARPROC)MACRO_ExtAbleItem}, + {"ExtInsertItem", NULL, 0, "SSSSUU", (FARPROC)MACRO_ExtInsertItem}, + {"ExtInsertMenu", NULL, 0, "SSSUU", (FARPROC)MACRO_ExtInsertMenu}, + {"FileExist", "FE", 1, "S", (FARPROC)MACRO_FileExist}, + {"FileOpen", "FO", 0, "", (FARPROC)MACRO_FileOpen}, + {"Find", NULL, 0, "", (FARPROC)MACRO_Find}, + {"Finder", "FD", 0, "", (FARPROC)MACRO_Finder}, + {"FloatingMenu", NULL, 0, "", (FARPROC)MACRO_FloatingMenu}, + {"Flush", "FH", 0, "", (FARPROC)MACRO_Flush}, + {"FocusWindow", NULL, 0, "S", (FARPROC)MACRO_FocusWindow}, + {"Generate", NULL, 0, "SUU", (FARPROC)MACRO_Generate}, + {"GotoMark", NULL, 0, "S", (FARPROC)MACRO_GotoMark}, + {"HelpOn", NULL, 0, "", (FARPROC)MACRO_HelpOn}, + {"HelpOnTop", NULL, 0, "", (FARPROC)MACRO_HelpOnTop}, + {"History", NULL, 0, "", (FARPROC)MACRO_History}, + {"InitMPrint", NULL, 1, "", (FARPROC)MACRO_InitMPrint}, + {"InsertItem", NULL, 0, "SSSSU", (FARPROC)MACRO_InsertItem}, + {"InsertMenu", NULL, 0, "SSU", (FARPROC)MACRO_InsertMenu}, + {"IfThen", "IF", 0, "BS", (FARPROC)MACRO_IfThen}, + {"IfThenElse", "IE", 0, "BSS", (FARPROC)MACRO_IfThenElse}, + {"IsBook", NULL, 1, "", (FARPROC)MACRO_IsBook}, + {"IsMark", NULL, 1, "S", (FARPROC)MACRO_IsMark}, + {"IsNotMark", "NM", 1, "S", (FARPROC)MACRO_IsNotMark}, + {"JumpContents", NULL, 0, "SS", (FARPROC)MACRO_JumpContents}, + {"JumpContext", "JC", 0, "SSU", (FARPROC)MACRO_JumpContext}, + {"JumpHash", "JH", 0, "SSU", (FARPROC)MACRO_JumpHash}, + {"JumpHelpOn", NULL, 0, "", (FARPROC)MACRO_JumpHelpOn}, + {"JumpID", "JI", 0, "SSS", (FARPROC)MACRO_JumpID}, + {"JumpKeyword", "JK", 0, "SSS", (FARPROC)MACRO_JumpKeyword}, + {"KLink", "KL", 0, "SUSS", (FARPROC)MACRO_KLink}, + {"Menu", "MU", 0, "", (FARPROC)MACRO_Menu}, + {"MPrintHash", NULL, 0, "U", (FARPROC)MACRO_MPrintHash}, + {"MPrintID", NULL, 0, "S", (FARPROC)MACRO_MPrintID}, + {"Next", NULL, 0, "", (FARPROC)MACRO_Next}, + {"NoShow", NULL, 0, "", (FARPROC)MACRO_NoShow}, + {"PopupContext", "PC", 0, "SU", (FARPROC)MACRO_PopupContext}, + {"PopupHash", NULL, 0, "SU", (FARPROC)MACRO_PopupHash}, + {"PopupId", "PI", 0, "SS", (FARPROC)MACRO_PopupId}, + {"PositionWindow", "PW", 0, "IIUUUS", (FARPROC)MACRO_PositionWindow}, + {"Prev", NULL, 0, "", (FARPROC)MACRO_Prev}, + {"Print", NULL, 0, "", (FARPROC)MACRO_Print}, + {"PrinterSetup", NULL, 0, "", (FARPROC)MACRO_PrinterSetup}, + {"RegisterRoutine", "RR", 0, "SSS", (FARPROC)MACRO_RegisterRoutine}, + {"RemoveAccelerator", "RA", 0, "UU", (FARPROC)MACRO_RemoveAccelerator}, + {"ResetMenu", NULL, 0, "", (FARPROC)MACRO_ResetMenu}, + {"SaveMark", NULL, 0, "S", (FARPROC)MACRO_SaveMark}, + {"Search", NULL, 0, "", (FARPROC)MACRO_Search}, + {"SetContents", NULL, 0, "SU", (FARPROC)MACRO_SetContents}, + {"SetHelpOnFile", NULL, 0, "S", (FARPROC)MACRO_SetHelpOnFile}, + {"SetPopupColor", "SPC",0, "UUU", (FARPROC)MACRO_SetPopupColor}, + {"ShellExecute", "SE", 0, "SSUUSS", (FARPROC)MACRO_ShellExecute}, + {"ShortCut", "SH", 0, "SSUUS", (FARPROC)MACRO_ShortCut}, + {"TCard", NULL, 0, "U", (FARPROC)MACRO_TCard}, + {"Test", NULL, 0, "U", (FARPROC)MACRO_Test}, + {"TestALink", NULL, 1, "S", (FARPROC)MACRO_TestALink}, + {"TestKLink", NULL, 1, "S", (FARPROC)MACRO_TestKLink}, + {"UncheckItem", "UI", 0, "S", (FARPROC)MACRO_UncheckItem}, + {"UpdateWindow", "UW", 0, "SS", (FARPROC)MACRO_UpdateWindow}, + {NULL, NULL, 0, NULL, NULL} +}; + +static struct MacroDesc*MACRO_Loaded /* = NULL */; +static unsigned MACRO_NumLoaded /* = 0 */; + +static int MACRO_DoLookUp(struct MacroDesc* start, const char* name, struct lexret* lr, unsigned len) +{ + struct MacroDesc* md; + + for (md = start; md->name && len != 0; md++, len--) + { + if (strcasecmp(md->name, name) == 0 || (md->alias != NULL && strcasecmp(md->alias, name) == 0)) + { + lr->proto = md->arguments; + lr->function = md->fn; + return md->isBool ? BOOL_FUNCTION : VOID_FUNCTION; + } + } + return EMPTY; +} + +int MACRO_Lookup(const char* name, struct lexret* lr) +{ + int ret; + + if ((ret = MACRO_DoLookUp(MACRO_Builtins, name, lr, -1)) != EMPTY) + return ret; + if (MACRO_Loaded && (ret = MACRO_DoLookUp(MACRO_Loaded, name, lr, MACRO_NumLoaded)) != EMPTY) + return ret; + + lr->string = name; + return IDENTIFIER; +} + +/******* helper functions *******/ + +static WINHELP_BUTTON** MACRO_LookupButton(WINHELP_WINDOW* win, LPCSTR name) +{ + WINHELP_BUTTON** b; + + for (b = &win->first_button; *b; b = &(*b)->next) + if (!lstrcmpi(name, (*b)->lpszID)) break; + return b; +} + +/******* real macro implementation *******/ + +void CALLBACK MACRO_About(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_AddAccelerator(LONG u1, LONG u2, LPCSTR str) +{ + WINE_FIXME("(%u, %u, \"%s\")\n", u1, u2, str); +} + +void CALLBACK MACRO_ALink(LPCSTR str1, LONG u, LPCSTR str2) +{ + WINE_FIXME("(\"%s\", %u, \"%s\")\n", str1, u, str2); +} + +void CALLBACK MACRO_Annotate(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_AppendItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4) +{ + WINE_FIXME("(\"%s\", \"%s\", \"%s\", \"%s\")\n", str1, str2, str3, str4); +} + +void CALLBACK MACRO_Back(void) +{ + WINHELP_WINDOW* win = Globals.active_win; + + WINE_TRACE("()\n"); + + if (win && win->backIndex >= 2) + WINHELP_CreateHelpWindow(win->back[--win->backIndex - 1], + win->info, SW_SHOW); +} + +void CALLBACK MACRO_BackFlush(void) +{ + WINHELP_WINDOW* win = Globals.active_win; + + WINE_TRACE("()\n"); + + if (win) + { + int i; + + for (i = 0; i < win->backIndex; i++) + { + HLPFILE_FreeHlpFile(win->back[i]->file); + win->back[i] = NULL; + } + win->backIndex = 0; + } +} + +void CALLBACK MACRO_BookmarkDefine(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_BookmarkMore(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_BrowseButtons(void) +{ + WINE_TRACE("()\n"); + + MACRO_CreateButton("BTN_PREV", "&<<", "Prev()"); + MACRO_CreateButton("BTN_NEXT", "&>>", "Next()"); +} + +void CALLBACK MACRO_ChangeButtonBinding(LPCSTR id, LPCSTR macro) +{ + WINHELP_WINDOW* win = Globals.active_win; + WINHELP_BUTTON* button; + WINHELP_BUTTON** b; + LONG size; + LPSTR ptr; + + WINE_TRACE("(\"%s\", \"%s\")\n", id, macro); + + b = MACRO_LookupButton(win, id); + if (!*b) {WINE_FIXME("Couldn't find button '%s'\n", id); return;} + + size = sizeof(WINHELP_BUTTON) + lstrlen(id) + + lstrlen((*b)->lpszName) + lstrlen(macro) + 3; + + button = HeapAlloc(GetProcessHeap(), 0, size); + if (!button) return; + + button->next = (*b)->next; + button->hWnd = (*b)->hWnd; + button->wParam = (*b)->wParam; + + ptr = (char*)button + sizeof(WINHELP_BUTTON); + + lstrcpy(ptr, id); + button->lpszID = ptr; + ptr += lstrlen(id) + 1; + + lstrcpy(ptr, (*b)->lpszName); + button->lpszName = ptr; + ptr += lstrlen((*b)->lpszName) + 1; + + lstrcpy(ptr, macro); + button->lpszMacro = ptr; + + *b = button; + + SendMessage(win->hMainWnd, WM_USER, 0, 0); +} + +void CALLBACK MACRO_ChangeEnable(LPCSTR id, LPCSTR macro) +{ + WINE_TRACE("(\"%s\", \"%s\")\n", id, macro); + + MACRO_ChangeButtonBinding(id, macro); + MACRO_EnableButton(id); +} + +void CALLBACK MACRO_ChangeItemBinding(LPCSTR str1, LPCSTR str2) +{ + WINE_FIXME("(\"%s\", \"%s\")\n", str1, str2); +} + +void CALLBACK MACRO_CheckItem(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); +} + +void CALLBACK MACRO_CloseSecondarys(void) +{ + WINHELP_WINDOW *win; + + WINE_TRACE("()\n"); + for (win = Globals.win_list; win; win = win->next) + if (win->lpszName && lstrcmpi(win->lpszName, "main")) + DestroyWindow(win->hMainWnd); +} + +void CALLBACK MACRO_CloseWindow(LPCSTR lpszWindow) +{ + WINHELP_WINDOW *win; + + WINE_TRACE("(\"%s\")\n", lpszWindow); + + if (!lpszWindow || !lpszWindow[0]) lpszWindow = "main"; + + for (win = Globals.win_list; win; win = win->next) + if (win->lpszName && !lstrcmpi(win->lpszName, lpszWindow)) + DestroyWindow(win->hMainWnd); +} + +void CALLBACK MACRO_Compare(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); +} + +void CALLBACK MACRO_Contents(void) +{ + WINE_TRACE("()\n"); + + if (Globals.active_win->page) + MACRO_JumpContents(Globals.active_win->page->file->lpszPath, NULL); +} + +void CALLBACK MACRO_ControlPanel(LPCSTR str1, LPCSTR str2, LONG u) +{ + WINE_FIXME("(\"%s\", \"%s\", %u)\n", str1, str2, u); +} + +void CALLBACK MACRO_CopyDialog(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_CopyTopic(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_CreateButton(LPCSTR id, LPCSTR name, LPCSTR macro) +{ + WINHELP_WINDOW *win = Globals.active_win; + WINHELP_BUTTON *button, **b; + LONG size; + LPSTR ptr; + + WINE_TRACE("(\"%s\", \"%s\", %s)\n", id, name, macro); + + size = sizeof(WINHELP_BUTTON) + lstrlen(id) + lstrlen(name) + lstrlen(macro) + 3; + + button = HeapAlloc(GetProcessHeap(), 0, size); + if (!button) return; + + button->next = 0; + button->hWnd = 0; + + ptr = (char*)button + sizeof(WINHELP_BUTTON); + + lstrcpy(ptr, id); + button->lpszID = ptr; + ptr += lstrlen(id) + 1; + + lstrcpy(ptr, name); + button->lpszName = ptr; + ptr += lstrlen(name) + 1; + + lstrcpy(ptr, macro); + button->lpszMacro = ptr; + + button->wParam = WH_FIRST_BUTTON; + for (b = &win->first_button; *b; b = &(*b)->next) + button->wParam = max(button->wParam, (*b)->wParam + 1); + *b = button; + + SendMessage(win->hMainWnd, WM_USER, 0, 0); +} + +void CALLBACK MACRO_DeleteItem(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); +} + +void CALLBACK MACRO_DeleteMark(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); +} + +void CALLBACK MACRO_DestroyButton(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); +} + +void CALLBACK MACRO_DisableButton(LPCSTR id) +{ + WINHELP_BUTTON** b; + + WINE_FIXME("(\"%s\")\n", id); + + b = MACRO_LookupButton(Globals.active_win, id); + if (!*b) {WINE_FIXME("Couldn't find button '%s'\n", id); return;} + + EnableWindow((*b)->hWnd, FALSE); +} + +void CALLBACK MACRO_DisableItem(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); +} + +void CALLBACK MACRO_EnableButton(LPCSTR id) +{ + WINHELP_BUTTON** b; + + WINE_TRACE("(\"%s\")\n", id); + + b = MACRO_LookupButton(Globals.active_win, id); + if (!*b) {WINE_FIXME("Couldn't find button '%s'\n", id); return;} + + EnableWindow((*b)->hWnd, TRUE); +} + +void CALLBACK MACRO_EnableItem(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); +} + +void CALLBACK MACRO_EndMPrint(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_ExecFile(LPCSTR str1, LPCSTR str2, LONG u, LPCSTR str3) +{ + WINE_FIXME("(\"%s\", \"%s\", %u, \"%s\")\n", str1, str2, u, str3); +} + +void CALLBACK MACRO_ExecProgram(LPCSTR str, LONG u) +{ + WINE_FIXME("(\"%s\", %u)\n", str, u); +} + +void CALLBACK MACRO_Exit(void) +{ + WINE_TRACE("()\n"); + + while (Globals.win_list) + DestroyWindow(Globals.win_list->hMainWnd); +} + +void CALLBACK MACRO_ExtAbleItem(LPCSTR str, LONG u) +{ + WINE_FIXME("(\"%s\", %u)\n", str, u); +} + +void CALLBACK MACRO_ExtInsertItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4, LONG u1, LONG u2) +{ + WINE_FIXME("(\"%s\", \"%s\", \"%s\", \"%s\", %u, %u)\n", str1, str2, str3, str4, u1, u2); +} + +void CALLBACK MACRO_ExtInsertMenu(LPCSTR str1, LPCSTR str2, LPCSTR str3, LONG u1, LONG u2) +{ + WINE_FIXME("(\"%s\", \"%s\", \"%s\", %u, %u)\n", str1, str2, str3, u1, u2); +} + +BOOL CALLBACK MACRO_FileExist(LPCSTR str) +{ + WINE_TRACE("(\"%s\")\n", str); + return GetFileAttributes(str) != INVALID_FILE_ATTRIBUTES; +} + +void CALLBACK MACRO_FileOpen(void) +{ + char szFile[MAX_PATH]; + + if (WINHELP_GetOpenFileName(szFile, MAX_PATH)) + { + HLPFILE* hlpfile = WINHELP_LookupHelpFile(szFile); + + WINHELP_CreateHelpWindowByHash(hlpfile, 0, + WINHELP_GetWindowInfo(hlpfile, "main"), SW_SHOWNORMAL); + } +} + +void CALLBACK MACRO_Find(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_Finder(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_FloatingMenu(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_Flush(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_FocusWindow(LPCSTR lpszWindow) +{ + WINHELP_WINDOW *win; + + WINE_TRACE("(\"%s\")\n", lpszWindow); + + if (!lpszWindow || !lpszWindow[0]) lpszWindow = "main"; + + for (win = Globals.win_list; win; win = win->next) + if (win->lpszName && !lstrcmpi(win->lpszName, lpszWindow)) + SetFocus(win->hMainWnd); +} + +void CALLBACK MACRO_Generate(LPCSTR str, LONG w, LONG l) +{ + WINE_FIXME("(\"%s\", %x, %x)\n", str, w, l); +} + +void CALLBACK MACRO_GotoMark(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); +} + +void CALLBACK MACRO_HelpOn(void) +{ + WINE_TRACE("()\n"); + MACRO_JumpContents((Globals.wVersion > 4) ? "winhelp32.hlp" : "winhelp.hlp", NULL); +} + +void CALLBACK MACRO_HelpOnTop(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_History(void) +{ + WINE_TRACE("()\n"); + + if (Globals.active_win && !Globals.active_win->hHistoryWnd) + { + HWND hWnd = CreateWindow(HISTORY_WIN_CLASS_NAME, "History", WS_OVERLAPPEDWINDOW, + 0, 0, 0, 0, 0, 0, Globals.hInstance, Globals.active_win); + ShowWindow(hWnd, SW_NORMAL); + } +} + +void CALLBACK MACRO_IfThen(BOOL b, LPCSTR t) +{ + if (b) MACRO_ExecuteMacro(t); +} + +void CALLBACK MACRO_IfThenElse(BOOL b, LPCSTR t, LPCSTR f) +{ + if (b) MACRO_ExecuteMacro(t); else MACRO_ExecuteMacro(f); +} + +BOOL CALLBACK MACRO_InitMPrint(void) +{ + WINE_FIXME("()\n"); + return FALSE; +} + +void CALLBACK MACRO_InsertItem(LPCSTR str1, LPCSTR str2, LPCSTR str3, LPCSTR str4, LONG u) +{ + WINE_FIXME("(\"%s\", \"%s\", \"%s\", \"%s\", %u)\n", str1, str2, str3, str4, u); +} + +void CALLBACK MACRO_InsertMenu(LPCSTR str1, LPCSTR str2, LONG u) +{ + WINE_FIXME("(\"%s\", \"%s\", %u)\n", str1, str2, u); +} + +BOOL CALLBACK MACRO_IsBook(void) +{ + WINE_TRACE("()\n"); + return Globals.isBook; +} + +BOOL CALLBACK MACRO_IsMark(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); + return FALSE; +} + +BOOL CALLBACK MACRO_IsNotMark(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); + return TRUE; +} + +void CALLBACK MACRO_JumpContents(LPCSTR lpszPath, LPCSTR lpszWindow) +{ + HLPFILE* hlpfile; + + WINE_TRACE("(\"%s\", \"%s\")\n", lpszPath, lpszWindow); + hlpfile = WINHELP_LookupHelpFile(lpszPath); + WINHELP_CreateHelpWindowByHash(hlpfile, 0, + WINHELP_GetWindowInfo(hlpfile, lpszWindow), + SW_NORMAL); +} + +void CALLBACK MACRO_JumpContext(LPCSTR lpszPath, LPCSTR lpszWindow, LONG context) +{ + HLPFILE* hlpfile; + + WINE_TRACE("(\"%s\", \"%s\", %d)\n", lpszPath, lpszWindow, context); + hlpfile = WINHELP_LookupHelpFile(lpszPath); + /* Some madness: what user calls 'context', hlpfile calls 'map' */ + WINHELP_CreateHelpWindowByMap(hlpfile, context, + WINHELP_GetWindowInfo(hlpfile, lpszWindow), + SW_NORMAL); +} + +void CALLBACK MACRO_JumpHash(LPCSTR lpszPath, LPCSTR lpszWindow, LONG lHash) +{ + HLPFILE* hlpfile; + + WINE_TRACE("(\"%s\", \"%s\", %u)\n", lpszPath, lpszWindow, lHash); + hlpfile = WINHELP_LookupHelpFile(lpszPath); + WINHELP_CreateHelpWindowByHash(hlpfile, lHash, + WINHELP_GetWindowInfo(hlpfile, lpszWindow), + SW_NORMAL); +} + +void CALLBACK MACRO_JumpHelpOn(void) +{ + WINE_FIXME("()\n"); +} + +/* FIXME: those two macros are wrong + * they should only contain 2 strings, path & window are coded as path>window + */ +void CALLBACK MACRO_JumpID(LPCSTR lpszPath, LPCSTR lpszWindow, LPCSTR topic_id) +{ + WINE_TRACE("(\"%s\", \"%s\", \"%s\")\n", lpszPath, lpszWindow, topic_id); + MACRO_JumpHash(lpszPath, lpszWindow, HLPFILE_Hash(topic_id)); +} + +void CALLBACK MACRO_JumpKeyword(LPCSTR lpszPath, LPCSTR lpszWindow, LPCSTR keyword) +{ + WINE_FIXME("(\"%s\", \"%s\", \"%s\")\n", lpszPath, lpszWindow, keyword); +} + +void CALLBACK MACRO_KLink(LPCSTR str1, LONG u, LPCSTR str2, LPCSTR str3) +{ + WINE_FIXME("(\"%s\", %u, \"%s\", \"%s\")\n", str1, u, str2, str3); +} + +void CALLBACK MACRO_Menu(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_MPrintHash(LONG u) +{ + WINE_FIXME("(%u)\n", u); +} + +void CALLBACK MACRO_MPrintID(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); +} + +void CALLBACK MACRO_Next(void) +{ + HLPFILE_PAGE* page; + + WINE_TRACE("()\n"); + page = Globals.active_win->page; + page = HLPFILE_PageByOffset(page->file, page->browse_fwd); + if (page) + { + page->file->wRefCount++; + WINHELP_CreateHelpWindow(page, Globals.active_win->info, SW_NORMAL); + } +} + +void CALLBACK MACRO_NoShow(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_PopupContext(LPCSTR str, LONG u) +{ + WINE_FIXME("(\"%s\", %u)\n", str, u); +} + +void CALLBACK MACRO_PopupHash(LPCSTR str, LONG u) +{ + WINE_FIXME("(\"%s\", %u)\n", str, u); +} + +void CALLBACK MACRO_PopupId(LPCSTR str1, LPCSTR str2) +{ + WINE_FIXME("(\"%s\", \"%s\")\n", str1, str2); +} + +void CALLBACK MACRO_PositionWindow(LONG i1, LONG i2, LONG u1, LONG u2, LONG u3, LPCSTR str) +{ + WINE_FIXME("(%i, %i, %u, %u, %u, \"%s\")\n", i1, i2, u1, u2, u3, str); +} + +void CALLBACK MACRO_Prev(void) +{ + HLPFILE_PAGE* page; + + WINE_TRACE("()\n"); + page = Globals.active_win->page; + page = HLPFILE_PageByOffset(page->file, page->browse_bwd); + if (page) + { + page->file->wRefCount++; + WINHELP_CreateHelpWindow(page, Globals.active_win->info, SW_NORMAL); + } +} + +void CALLBACK MACRO_Print(void) +{ + PRINTDLG printer; + + WINE_TRACE("()\n"); + + printer.lStructSize = sizeof(printer); + printer.hwndOwner = Globals.active_win->hMainWnd; + printer.hInstance = Globals.hInstance; + printer.hDevMode = 0; + printer.hDevNames = 0; + printer.hDC = 0; + printer.Flags = 0; + printer.nFromPage = 0; + printer.nToPage = 0; + printer.nMinPage = 0; + printer.nMaxPage = 0; + printer.nCopies = 0; + printer.lCustData = 0; + printer.lpfnPrintHook = 0; + printer.lpfnSetupHook = 0; + printer.lpPrintTemplateName = 0; + printer.lpSetupTemplateName = 0; + printer.hPrintTemplate = 0; + printer.hSetupTemplate = 0; + + if (PrintDlgA(&printer)) { + WINE_FIXME("Print()\n"); + } +} + +void CALLBACK MACRO_PrinterSetup(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_RegisterRoutine(LPCSTR dll_name, LPCSTR proc, LPCSTR args) +{ + FARPROC fn = NULL; + int size; + WINHELP_DLL* dll; + + WINE_TRACE("(\"%s\", \"%s\", \"%s\")\n", dll_name, proc, args); + + /* FIXME: are the registered DLLs global or linked to the current file ??? + * We assume globals (as we did for macros, but is this really the case ???) + */ + for (dll = Globals.dlls; dll; dll = dll->next) + { + if (!strcmp(dll->name, dll_name)) break; + } + if (!dll) + { + HANDLE hLib = LoadLibrary(dll_name); + + /* FIXME: the library will not be unloaded until exit of program + * We don't send the DW_TERM message + */ + WINE_TRACE("Loading %s\n", dll_name); + /* FIXME: should look in the directory where current hlpfile + * is loaded from + */ + if (hLib == NULL) + { + /* FIXME: internationalisation for error messages */ + WINE_FIXME("Cannot find dll %s\n", dll_name); + } + else if ((dll = HeapAlloc(GetProcessHeap(), 0, sizeof(*dll)))) + { + dll->hLib = hLib; + dll->name = strdup(dll_name); /* FIXME */ + dll->next = Globals.dlls; + Globals.dlls = dll; + dll->handler = (WINHELP_LDLLHandler)GetProcAddress(dll->hLib, "LDLLHandler"); + dll->class = dll->handler ? (dll->handler)(DW_WHATMSG, 0, 0) : DC_NOMSG; + WINE_TRACE("Got class %x for DLL %s\n", dll->class, dll_name); + if (dll->class & DC_INITTERM) dll->handler(DW_INIT, 0, 0); + if (dll->class & DC_CALLBACKS) dll->handler(DW_CALLBACKS, (DWORD)Callbacks, 0); + } + else WINE_WARN("OOM\n"); + } + if (dll && !(fn = GetProcAddress(dll->hLib, proc))) + { + /* FIXME: internationalisation for error messages */ + WINE_FIXME("Cannot find proc %s in dll %s\n", dll_name, proc); + } + + size = ++MACRO_NumLoaded * sizeof(struct MacroDesc); + if (!MACRO_Loaded) MACRO_Loaded = HeapAlloc(GetProcessHeap(), 0, size); + else MACRO_Loaded = HeapReAlloc(GetProcessHeap(), 0, MACRO_Loaded, size); + MACRO_Loaded[MACRO_NumLoaded - 1].name = strdup(proc); /* FIXME */ + MACRO_Loaded[MACRO_NumLoaded - 1].alias = NULL; + MACRO_Loaded[MACRO_NumLoaded - 1].isBool = 0; + MACRO_Loaded[MACRO_NumLoaded - 1].arguments = strdup(args); /* FIXME */ + MACRO_Loaded[MACRO_NumLoaded - 1].fn = fn; + WINE_TRACE("Added %s(%s) at %p\n", proc, args, fn); +} + +void CALLBACK MACRO_RemoveAccelerator(LONG u1, LONG u2) +{ + WINE_FIXME("(%u, %u)\n", u1, u2); +} + +void CALLBACK MACRO_ResetMenu(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_SaveMark(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); +} + +void CALLBACK MACRO_Search(void) +{ + WINE_FIXME("()\n"); +} + +void CALLBACK MACRO_SetContents(LPCSTR str, LONG u) +{ + WINE_FIXME("(\"%s\", %u)\n", str, u); +} + +void CALLBACK MACRO_SetHelpOnFile(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); +} + +void CALLBACK MACRO_SetPopupColor(LONG u1, LONG u2, LONG u3) +{ + WINE_FIXME("(%u, %u, %u)\n", u1, u2, u3); +} + +void CALLBACK MACRO_ShellExecute(LPCSTR str1, LPCSTR str2, LONG u1, LONG u2, LPCSTR str3, LPCSTR str4) +{ + WINE_FIXME("(\"%s\", \"%s\", %u, %u, \"%s\", \"%s\")\n", str1, str2, u1, u2, str3, str4); +} + +void CALLBACK MACRO_ShortCut(LPCSTR str1, LPCSTR str2, LONG w, LONG l, LPCSTR str) +{ + WINE_FIXME("(\"%s\", \"%s\", %x, %x, \"%s\")\n", str1, str2, w, l, str); +} + +void CALLBACK MACRO_TCard(LONG u) +{ + WINE_FIXME("(%u)\n", u); +} + +void CALLBACK MACRO_Test(LONG u) +{ + WINE_FIXME("(%u)\n", u); +} + +BOOL CALLBACK MACRO_TestALink(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); + return FALSE; +} + +BOOL CALLBACK MACRO_TestKLink(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); + return FALSE; +} + +void CALLBACK MACRO_UncheckItem(LPCSTR str) +{ + WINE_FIXME("(\"%s\")\n", str); +} + +void CALLBACK MACRO_UpdateWindow(LPCSTR str1, LPCSTR str2) +{ + WINE_FIXME("(\"%s\", \"%s\")\n", str1, str2); +} diff --git a/reactos/base/applications/winhelp/macro.h b/reactos/base/applications/winhelp/macro.h new file mode 100644 index 00000000000..68be1c69186 --- /dev/null +++ b/reactos/base/applications/winhelp/macro.h @@ -0,0 +1,140 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Eric Pouech + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __MACRO_H__ +#define __MACRO_H__ + +#include + +#include "windef.h" +#include "winbase.h" + +struct lexret { + LPCSTR proto; + BOOL bool; + LONG integer; + LPCSTR string; + FARPROC function; +}; + +extern struct lexret yylval; + +BOOL MACRO_ExecuteMacro(LPCSTR); +int MACRO_Lookup(const char* name, struct lexret* lr); + +enum token_types {EMPTY, VOID_FUNCTION, BOOL_FUNCTION, INTEGER, STRING, IDENTIFIER}; +void CALLBACK MACRO_About(void); +void CALLBACK MACRO_AddAccelerator(LONG, LONG, LPCSTR); +void CALLBACK MACRO_ALink(LPCSTR, LONG, LPCSTR); +void CALLBACK MACRO_Annotate(void); +void CALLBACK MACRO_AppendItem(LPCSTR, LPCSTR, LPCSTR, LPCSTR); +void CALLBACK MACRO_Back(void); +void CALLBACK MACRO_BackFlush(void); +void CALLBACK MACRO_BookmarkDefine(void); +void CALLBACK MACRO_BookmarkMore(void); +void CALLBACK MACRO_BrowseButtons(void); +void CALLBACK MACRO_ChangeButtonBinding(LPCSTR, LPCSTR); +void CALLBACK MACRO_ChangeEnable(LPCSTR, LPCSTR); +void CALLBACK MACRO_ChangeItemBinding(LPCSTR, LPCSTR); +void CALLBACK MACRO_CheckItem(LPCSTR); +void CALLBACK MACRO_CloseSecondarys(void); +void CALLBACK MACRO_CloseWindow(LPCSTR); +void CALLBACK MACRO_Compare(LPCSTR); +void CALLBACK MACRO_Contents(void); +void CALLBACK MACRO_ControlPanel(LPCSTR, LPCSTR, LONG); +void CALLBACK MACRO_CopyDialog(void); +void CALLBACK MACRO_CopyTopic(void); +void CALLBACK MACRO_CreateButton(LPCSTR, LPCSTR, LPCSTR); +void CALLBACK MACRO_DeleteItem(LPCSTR); +void CALLBACK MACRO_DeleteMark(LPCSTR); +void CALLBACK MACRO_DestroyButton(LPCSTR); +void CALLBACK MACRO_DisableButton(LPCSTR); +void CALLBACK MACRO_DisableItem(LPCSTR); +void CALLBACK MACRO_EnableButton(LPCSTR); +void CALLBACK MACRO_EnableItem(LPCSTR); +void CALLBACK MACRO_EndMPrint(void); +void CALLBACK MACRO_ExecFile(LPCSTR, LPCSTR, LONG, LPCSTR); +void CALLBACK MACRO_ExecProgram(LPCSTR, LONG); +void CALLBACK MACRO_Exit(void); +void CALLBACK MACRO_ExtAbleItem(LPCSTR, LONG); +void CALLBACK MACRO_ExtInsertItem(LPCSTR, LPCSTR, LPCSTR, LPCSTR, LONG, LONG); +void CALLBACK MACRO_ExtInsertMenu(LPCSTR, LPCSTR, LPCSTR, LONG, LONG); +BOOL CALLBACK MACRO_FileExist(LPCSTR); +void CALLBACK MACRO_FileOpen(void); +void CALLBACK MACRO_Find(void); +void CALLBACK MACRO_Finder(void); +void CALLBACK MACRO_FloatingMenu(void); +void CALLBACK MACRO_Flush(void); +void CALLBACK MACRO_FocusWindow(LPCSTR); +void CALLBACK MACRO_Generate(LPCSTR, LONG, LONG); +void CALLBACK MACRO_GotoMark(LPCSTR); +void CALLBACK MACRO_HelpOn(void); +void CALLBACK MACRO_HelpOnTop(void); +void CALLBACK MACRO_History(void); +void CALLBACK MACRO_IfThen(BOOL, LPCSTR); +void CALLBACK MACRO_IfThenElse(BOOL, LPCSTR, LPCSTR); +BOOL CALLBACK MACRO_InitMPrint(void); +void CALLBACK MACRO_InsertItem(LPCSTR, LPCSTR, LPCSTR, LPCSTR, LONG); +void CALLBACK MACRO_InsertMenu(LPCSTR, LPCSTR, LONG); +BOOL CALLBACK MACRO_IsBook(void); +BOOL CALLBACK MACRO_IsMark(LPCSTR); +BOOL CALLBACK MACRO_IsNotMark(LPCSTR); +void CALLBACK MACRO_JumpContents(LPCSTR, LPCSTR); +void CALLBACK MACRO_JumpContext(LPCSTR, LPCSTR, LONG); +void CALLBACK MACRO_JumpHash(LPCSTR, LPCSTR, LONG); +void CALLBACK MACRO_JumpHelpOn(void); +void CALLBACK MACRO_JumpID(LPCSTR, LPCSTR, LPCSTR); +void CALLBACK MACRO_JumpKeyword(LPCSTR, LPCSTR, LPCSTR); +void CALLBACK MACRO_KLink(LPCSTR, LONG, LPCSTR, LPCSTR); +void CALLBACK MACRO_Menu(void); +void CALLBACK MACRO_MPrintHash(LONG); +void CALLBACK MACRO_MPrintID(LPCSTR); +void CALLBACK MACRO_Next(void); +void CALLBACK MACRO_NoShow(void); +void CALLBACK MACRO_PopupContext(LPCSTR, LONG); +void CALLBACK MACRO_PopupHash(LPCSTR, LONG); +void CALLBACK MACRO_PopupId(LPCSTR, LPCSTR); +void CALLBACK MACRO_PositionWindow(LONG, LONG, LONG, LONG, LONG, LPCSTR); +void CALLBACK MACRO_Prev(void); +void CALLBACK MACRO_Print(void); +void CALLBACK MACRO_PrinterSetup(void); +void CALLBACK MACRO_RegisterRoutine(LPCSTR, LPCSTR, LPCSTR); +void CALLBACK MACRO_RemoveAccelerator(LONG, LONG); +void CALLBACK MACRO_ResetMenu(void); +void CALLBACK MACRO_SaveMark(LPCSTR); +void CALLBACK MACRO_Search(void); +void CALLBACK MACRO_SetContents(LPCSTR, LONG); +void CALLBACK MACRO_SetHelpOnFile(LPCSTR); +void CALLBACK MACRO_SetPopupColor(LONG, LONG, LONG); +void CALLBACK MACRO_ShellExecute(LPCSTR, LPCSTR, LONG, LONG, LPCSTR, LPCSTR); +void CALLBACK MACRO_ShortCut(LPCSTR, LPCSTR, LONG, LONG, LPCSTR); +void CALLBACK MACRO_TCard(LONG); +void CALLBACK MACRO_Test(LONG); +BOOL CALLBACK MACRO_TestALink(LPCSTR); +BOOL CALLBACK MACRO_TestKLink(LPCSTR); +void CALLBACK MACRO_UncheckItem(LPCSTR); +void CALLBACK MACRO_UpdateWindow(LPCSTR, LPCSTR); + +/* Local Variables: */ +/* c-file-style: "GNU" */ +/* End: */ + +#endif /* __MACRO_H__ */ diff --git a/reactos/base/applications/winhelp/macro.lex.l b/reactos/base/applications/winhelp/macro.lex.l new file mode 100644 index 00000000000..f6aa0d92998 --- /dev/null +++ b/reactos/base/applications/winhelp/macro.lex.l @@ -0,0 +1,295 @@ +%{ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Eric Pouech + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ +%} +%option nounput interactive 8bit +%x quote +%{ +#include +#include "macro.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winhelp); + +static LPCSTR macroptr; +static LPSTR strptr; +static int quote_stack[32]; +static int quote_stk_idx = 0; +struct lexret yylval; + +#define YY_INPUT(buf,result,max_size)\ + if ((result = *macroptr ? 1 : 0)) buf[0] = *macroptr++; + +%} +%% + +[-+]?[0-9]+ yylval.integer = strtol(yytext, NULL, 10); return INTEGER; +[-+]?0[xX][0-9a-f]+ yylval.integer = strtol(yytext, NULL, 16); return INTEGER; + +[a-zA-Z][_0-9a-zA-Z]* return MACRO_Lookup(yytext, &yylval); + +\` | +\" | +\' | +\` | +\" | +\' { + if (quote_stk_idx == 0 || + (yytext[0] == '\"' && quote_stack[quote_stk_idx - 1] != '\"') || + (yytext[0] == '`')) + { + /* opening a new one */ + if (quote_stk_idx == 0) + { + strptr = HeapAlloc(GetProcessHeap(), 0, strlen(macroptr) + 1); + yylval.string = strptr; + BEGIN(quote); + } + else *strptr++ = yytext[0]; + quote_stack[quote_stk_idx++] = yytext[0]; + assert(quote_stk_idx < sizeof(quote_stack) / sizeof(quote_stack[0])); + } + else + { + if (yytext[0] == '`') assert(0); + /* close the current quote */ + if (--quote_stk_idx == 0) + { + BEGIN INITIAL; + *strptr++ = '\0'; + return STRING; + } + else *strptr++ = yytext[0]; + } +} + +. *strptr++ = yytext[0]; +\\. *strptr++ = yytext[1]; +<> return 0; + +" " +. return yytext[0]; +%% + +#if 0 +/* all code for testing macros */ +#include "winhelp.h" +static CHAR szTestMacro[256]; + +static LRESULT CALLBACK MACRO_TestDialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_COMMAND && wParam == IDOK) + { + GetDlgItemText(hDlg, 99, szTestMacro, sizeof(szTestMacro)); + EndDialog(hDlg, IDOK); + return TRUE; + } + return FALSE; +} + +void macro_test(void) +{ + WNDPROC lpfnDlg = MakeProcInstance(MACRO_TestDialogProc, Globals.hInstance); + DialogBox(Globals.hInstance, STRING_DIALOG_TEST, Globals.active_win->hMainWnd, (DLGPROC)lpfnDlg); + FreeProcInstance(lpfnDlg); + macro = szTestMacro; +} +#endif + +/* small helper function for debug messages */ +static const char* ts(int t) +{ + static char c[2] = {0,0}; + + switch (t) + { + case EMPTY: return "EMPTY"; + case VOID_FUNCTION: return "VOID_FUNCTION"; + case BOOL_FUNCTION: return "BOOL_FUNCTION"; + case INTEGER: return "INTEGER"; + case STRING: return "STRING"; + case IDENTIFIER: return "IDENTIFIER"; + default: c[0] = (char)t; return c; + } +} + +static int MACRO_CallBoolFunc(FARPROC fn, const char* args, void** ret); + +/****************************************************************** + * MACRO_CheckArgs + * + * checks number of arguments against prototype, and stores arguments on + * stack pa for later call + * returns -1 on error, otherwise the number of pushed parameters + */ +static int MACRO_CheckArgs(void* pa[], unsigned max, const char* args) +{ + int t; + int len = 0, idx = 0; + + WINE_TRACE("Checking %s\n", args); + + if (yylex() != '(') {WINE_WARN("missing (\n");return -1;} + + if (*args) + { + len = strlen(args); + for (;;) + { + t = yylex(); + WINE_TRACE("Got %s <=> %c\n", ts(t), *args); + + switch (*args) + { + case 'S': + if (t != STRING) + {WINE_WARN("missing S\n");return -1;} + pa[idx] = (void*)yylval.string; + break; + case 'U': + case 'I': + if (t != INTEGER) + {WINE_WARN("missing U\n");return -1;} + pa[idx] = (void*)yylval.integer; + break; + case 'B': + if (t != BOOL_FUNCTION) + {WINE_WARN("missing B\n");return -1;} + if (MACRO_CallBoolFunc(yylval.function, yylval.proto, &pa[idx]) == 0) + return -1; + break; + default: + WINE_WARN("unexpected %s while args is %c\n", ts(t), *args); + return -1; + } + idx++; + if (*++args == '\0') break; + t = yylex(); + if (t == ')') goto CheckArgs_end; + if (t != ',') {WINE_WARN("missing ,\n");return -1;} + if (idx >= max) {WINE_FIXME("stack overflow (%d)\n", max);return -1;} + } + } + if (yylex() != ')') {WINE_WARN("missing )\n");return -1;} + +CheckArgs_end: + while (len > idx) pa[--len] = NULL; + return idx; +} + +/****************************************************************** + * MACRO_CallBoolFunc + * + * Invokes boolean function fn, which arguments are defined by args + * stores bool result into ret + */ +static int MACRO_CallBoolFunc(FARPROC fn, const char* args, void** ret) +{ + void* pa[2]; + int idx = MACRO_CheckArgs(pa, sizeof(pa)/sizeof(pa[0]), args); + + if (idx < 0) return 0; + if (!fn) return 1; + + WINE_TRACE("calling with %u pmts\n", idx); + + switch (strlen(args)) + { + case 0: *ret = (void*)(fn)(); break; + case 1: *ret = (void*)(fn)(pa[0]); break; + default: WINE_FIXME("NIY\n"); + } + + return 1; +} + +/****************************************************************** + * MACRO_CallVoidFunc + * + * + */ +static int MACRO_CallVoidFunc(FARPROC fn, const char* args) +{ + void* pa[6]; + int idx = MACRO_CheckArgs(pa, sizeof(pa)/sizeof(pa[0]), args); + + if (idx < 0) return 0; + if (!fn) return 1; + + WINE_TRACE("calling %p with %u pmts\n", fn, idx); + + switch (strlen(args)) + { + case 0: (fn)(); break; + case 1: (fn)(pa[0]); break; + case 2: (fn)(pa[0],pa[1]); break; + case 3: (fn)(pa[0],pa[1],pa[2]); break; + case 4: (fn)(pa[0],pa[1],pa[2],pa[3]); break; + case 5: (fn)(pa[0],pa[1],pa[2],pa[3],pa[4]); break; + case 6: (fn)(pa[0],pa[1],pa[2],pa[3],pa[4],pa[5]); break; + default: WINE_FIXME("NIY\n"); + } + + return 1; +} + +BOOL MACRO_ExecuteMacro(LPCSTR macro) +{ + int t; + + //WINE_TRACE("%s\n", wine_dbgstr_a(macro)); + + macroptr = macro; + + while ((t = yylex()) != EMPTY) + { + switch (t) + { + case VOID_FUNCTION: + WINE_TRACE("got type void func(%s)\n", yylval.proto); + MACRO_CallVoidFunc(yylval.function, yylval.proto); + break; + case BOOL_FUNCTION: + WINE_WARN("got type bool func(%s)\n", yylval.proto); + break; + default: + WINE_WARN("got unexpected type %s\n", ts(t)); + return 0; + } + switch (t = yylex()) + { + case EMPTY: return 1; + case ';': break; + default: return 0; + } + } + + HeapFree(GetProcessHeap(), 0, strptr); + strptr = NULL; + quote_stk_idx = 0; + + return 1; +} + +#ifndef yywrap +int yywrap(void) { return 1; } +#endif diff --git a/reactos/base/applications/winhelp/rsrc.rc b/reactos/base/applications/winhelp/rsrc.rc new file mode 100644 index 00000000000..0698c510e68 --- /dev/null +++ b/reactos/base/applications/winhelp/rsrc.rc @@ -0,0 +1,48 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Sylvain Petreolle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include "winhelp.h" +#include "winhelp_res.h" + +#include "Bg.rc" +#include "Cs.rc" +#include "Da.rc" +#include "De.rc" +#include "En.rc" +//#include "Eo.rc" +#include "Es.rc" +#include "Fi.rc" +#include "Fr.rc" +#include "Hu.rc" +#include "It.rc" +#include "Ko.rc" +#include "Nl.rc" +#include "No.rc" +#include "Pl.rc" +#include "Pt.rc" +#include "Ru.rc" +#include "Si.rc" +#include "Sk.rc" +#include "Sw.rc" +#include "Tr.rc" +#include "Wa.rc" +#include "Zh.rc" diff --git a/reactos/base/applications/winhelp/string.c b/reactos/base/applications/winhelp/string.c new file mode 100644 index 00000000000..df85cf466eb --- /dev/null +++ b/reactos/base/applications/winhelp/string.c @@ -0,0 +1,35 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +/* Class names */ + +const char MAIN_WIN_CLASS_NAME[] = "MS_WINHELP"; +const char BUTTON_BOX_WIN_CLASS_NAME[] = "WHButtonBox"; +const char TEXT_WIN_CLASS_NAME[] = "WHText"; +const char SHADOW_WIN_CLASS_NAME[] = "WHShadow"; +const char HISTORY_WIN_CLASS_NAME[] = "WHHistory"; +const char STRING_BUTTON[] = "BUTTON"; + +/* Resource names */ +const char STRING_DIALOG_TEST[] = "DIALOG_TEST"; + +/* Local Variables: */ +/* c-file-style: "GNU" */ +/* End: */ diff --git a/reactos/base/applications/winhelp/winhelp.c b/reactos/base/applications/winhelp/winhelp.c new file mode 100644 index 00000000000..8905d6e222e --- /dev/null +++ b/reactos/base/applications/winhelp/winhelp.c @@ -0,0 +1,1930 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * 2002 Sylvain Petreolle + * 2002 Eric Pouech + * 2004 Ken Belleau + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "commdlg.h" +#include "winhelp.h" +#include "winhelp_res.h" +#include "shellapi.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(winhelp); + +static BOOL WINHELP_RegisterWinClasses(void); +static LRESULT CALLBACK WINHELP_MainWndProc(HWND, UINT, WPARAM, LPARAM); +static LRESULT CALLBACK WINHELP_TextWndProc(HWND, UINT, WPARAM, LPARAM); +static LRESULT CALLBACK WINHELP_ButtonBoxWndProc(HWND, UINT, WPARAM, LPARAM); +static LRESULT CALLBACK WINHELP_ButtonWndProc(HWND, UINT, WPARAM, LPARAM); +static LRESULT CALLBACK WINHELP_HistoryWndProc(HWND, UINT, WPARAM, LPARAM); +static LRESULT CALLBACK WINHELP_ShadowWndProc(HWND, UINT, WPARAM, LPARAM); +static void WINHELP_CheckPopup(UINT); +static BOOL WINHELP_SplitLines(HWND hWnd, LPSIZE); +static void WINHELP_InitFonts(HWND hWnd); +static void WINHELP_DeleteLines(WINHELP_WINDOW*); +static void WINHELP_DeleteWindow(WINHELP_WINDOW*); +static void WINHELP_SetupText(HWND hWnd); +static WINHELP_LINE_PART* WINHELP_IsOverLink(WINHELP_WINDOW*, WPARAM, LPARAM); + +WINHELP_GLOBALS Globals = {3, NULL, NULL, 0, TRUE, NULL, NULL, NULL, NULL}; + + +/*********************************************************************** + * + * WINHELP_GetOpenFileName + */ +BOOL WINHELP_GetOpenFileName(LPSTR lpszFile, int len) +{ + OPENFILENAME openfilename; + CHAR szDir[MAX_PATH]; + CHAR szzFilter[2 * MAX_STRING_LEN + 100]; + LPSTR p = szzFilter; + + WINE_TRACE("()\n"); + + LoadString(Globals.hInstance, STID_HELP_FILES_HLP, p, MAX_STRING_LEN); + p += strlen(p) + 1; + lstrcpy(p, "*.hlp"); + p += strlen(p) + 1; + LoadString(Globals.hInstance, STID_ALL_FILES, p, MAX_STRING_LEN); + p += strlen(p) + 1; + lstrcpy(p, "*.*"); + p += strlen(p) + 1; + *p = '\0'; + + GetCurrentDirectory(sizeof(szDir), szDir); + + lpszFile[0]='\0'; + + openfilename.lStructSize = sizeof(OPENFILENAME); + openfilename.hwndOwner = NULL; + openfilename.hInstance = Globals.hInstance; + openfilename.lpstrFilter = szzFilter; + openfilename.lpstrCustomFilter = 0; + openfilename.nMaxCustFilter = 0; + openfilename.nFilterIndex = 1; + openfilename.lpstrFile = lpszFile; + openfilename.nMaxFile = len; + openfilename.lpstrFileTitle = 0; + openfilename.nMaxFileTitle = 0; + openfilename.lpstrInitialDir = szDir; + openfilename.lpstrTitle = 0; + openfilename.Flags = 0; + openfilename.nFileOffset = 0; + openfilename.nFileExtension = 0; + openfilename.lpstrDefExt = 0; + openfilename.lCustData = 0; + openfilename.lpfnHook = 0; + openfilename.lpTemplateName = 0; + + return GetOpenFileName(&openfilename); +} + +/*********************************************************************** + * + * WINHELP_LookupHelpFile + */ +HLPFILE* WINHELP_LookupHelpFile(LPCSTR lpszFile) +{ + HLPFILE* hlpfile; + char szFullName[MAX_PATH]; + char szAddPath[MAX_PATH]; + char *p; + + /* + * NOTE: This is needed by popup windows only. + * In other cases it's not needed but does not hurt though. + */ + if (Globals.active_win && Globals.active_win->page && Globals.active_win->page->file) + { + strcpy(szAddPath, Globals.active_win->page->file->lpszPath); + p = strrchr(szAddPath, '\\'); + if (p) *p = 0; + } + + /* + * FIXME: Should we swap conditions? + */ + if (!SearchPath(NULL, lpszFile, ".hlp", MAX_PATH, szFullName, NULL) && + !SearchPath(szAddPath, lpszFile, ".hlp", MAX_PATH, szFullName, NULL)) + { + if (WINHELP_MessageBoxIDS_s(STID_FILE_NOT_FOUND_s, lpszFile, STID_WHERROR, + MB_YESNO|MB_ICONQUESTION) != IDYES) + return NULL; + if (!WINHELP_GetOpenFileName(szFullName, MAX_PATH)) + return NULL; + } + hlpfile = HLPFILE_ReadHlpFile(szFullName); + if (!hlpfile) + WINHELP_MessageBoxIDS_s(STID_HLPFILE_ERROR_s, lpszFile, + STID_WHERROR, MB_OK|MB_ICONSTOP); + return hlpfile; +} + +/****************************************************************** + * WINHELP_GetWindowInfo + * + * + */ +HLPFILE_WINDOWINFO* WINHELP_GetWindowInfo(HLPFILE* hlpfile, LPCSTR name) +{ + static HLPFILE_WINDOWINFO mwi; + unsigned int i; + + if (!name || !name[0]) + name = Globals.active_win->lpszName; + + if (hlpfile) + for (i = 0; i < hlpfile->numWindows; i++) + if (!strcmp(hlpfile->windows[i].name, name)) + return &hlpfile->windows[i]; + + if (strcmp(name, "main") != 0) + { + WINE_FIXME("Couldn't find window info for %s\n", name); + assert(0); + return NULL; + } + if (!mwi.name[0]) + { + strcpy(mwi.type, "primary"); + strcpy(mwi.name, "main"); + if (!LoadString(Globals.hInstance, STID_WINE_HELP, + mwi.caption, sizeof(mwi.caption))) + strcpy(mwi.caption, hlpfile->lpszTitle); + mwi.origin.x = mwi.origin.y = mwi.size.cx = mwi.size.cy = CW_USEDEFAULT; + mwi.style = SW_SHOW; + mwi.win_style = WS_OVERLAPPEDWINDOW; + mwi.sr_color = mwi.sr_color = 0xFFFFFF; + } + return &mwi; +} + +/****************************************************************** + * HLPFILE_GetPopupWindowInfo + * + * + */ +static HLPFILE_WINDOWINFO* WINHELP_GetPopupWindowInfo(HLPFILE* hlpfile, HWND hParentWnd, POINT* mouse) +{ + static HLPFILE_WINDOWINFO wi; + + RECT parent_rect; + + wi.type[0] = wi.name[0] = wi.caption[0] = '\0'; + + /* Calculate horizontal size and position of a popup window */ + GetWindowRect(hParentWnd, &parent_rect); + wi.size.cx = (parent_rect.right - parent_rect.left) / 2; + wi.size.cy = 10; /* need a non null value, so that border are taken into account while computing */ + + wi.origin = *mouse; + ClientToScreen(hParentWnd, &wi.origin); + wi.origin.x -= wi.size.cx / 2; + wi.origin.x = min(wi.origin.x, GetSystemMetrics(SM_CXSCREEN) - wi.size.cx); + wi.origin.x = max(wi.origin.x, 0); + + wi.style = SW_SHOW; + wi.win_style = WS_POPUPWINDOW; + wi.sr_color = wi.sr_color = 0xFFFFFF; + + return &wi; +} + +/*********************************************************************** + * + * WinMain + */ +int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show) +{ + MSG msg; + LONG lHash = 0; + HLPFILE* hlpfile; + static CHAR default_wndname[] = "main"; + LPSTR wndname = default_wndname; + WINHELP_DLL* dll; + + Globals.hInstance = hInstance; + + /* Get options */ + while (*cmdline && (*cmdline == ' ' || *cmdline == '-')) + { + CHAR option; + LPCSTR topic_id; + if (*cmdline++ == ' ') continue; + + option = *cmdline; + if (option) cmdline++; + while (*cmdline && *cmdline == ' ') cmdline++; + switch (option) + { + case 'i': + case 'I': + topic_id = cmdline; + while (*cmdline && *cmdline != ' ') cmdline++; + if (*cmdline) *cmdline++ = '\0'; + lHash = HLPFILE_Hash(topic_id); + break; + + case '3': + case '4': + Globals.wVersion = option - '0'; + break; + + case 'x': + show = SW_HIDE; + Globals.isBook = FALSE; + break; + + default: + WINE_FIXME("Unsupported cmd line: %s\n", cmdline); + break; + } + } + + /* Create primary window */ + if (!WINHELP_RegisterWinClasses()) + { + WINE_FIXME("Couldn't register classes\n"); + return 0; + } + + if (*cmdline) + { + char* ptr; + if ((*cmdline == '"') && (ptr = strchr(cmdline+1, '"'))) + { + cmdline++; + *ptr = '\0'; + } + if ((ptr = strchr(cmdline, '>'))) + { + *ptr = '\0'; + wndname = ptr + 1; + } + hlpfile = WINHELP_LookupHelpFile(cmdline); + if (!hlpfile) return 0; + } + else hlpfile = NULL; + WINHELP_CreateHelpWindowByHash(hlpfile, lHash, + WINHELP_GetWindowInfo(hlpfile, wndname), show); + + /* Message loop */ + while (GetMessage(&msg, 0, 0, 0)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + for (dll = Globals.dlls; dll; dll = dll->next) + { + if (dll->class & DC_INITTERM) dll->handler(DW_TERM, 0, 0); + } + return 0; +} + +/*********************************************************************** + * + * RegisterWinClasses + */ +static BOOL WINHELP_RegisterWinClasses(void) +{ + WNDCLASS class_main, class_button_box, class_text, class_shadow, class_history; + + class_main.style = CS_HREDRAW | CS_VREDRAW; + class_main.lpfnWndProc = WINHELP_MainWndProc; + class_main.cbClsExtra = 0; + class_main.cbWndExtra = sizeof(LONG); + class_main.hInstance = Globals.hInstance; + class_main.hIcon = LoadIcon(0, IDI_APPLICATION); + class_main.hCursor = LoadCursor(0, IDC_ARROW); + class_main.hbrBackground = GetStockObject(WHITE_BRUSH); + class_main.lpszMenuName = 0; + class_main.lpszClassName = MAIN_WIN_CLASS_NAME; + + class_button_box = class_main; + class_button_box.lpfnWndProc = WINHELP_ButtonBoxWndProc; + class_button_box.hbrBackground = GetStockObject(GRAY_BRUSH); + class_button_box.lpszClassName = BUTTON_BOX_WIN_CLASS_NAME; + + class_text = class_main; + class_text.lpfnWndProc = WINHELP_TextWndProc; + class_text.hbrBackground = 0; + class_text.lpszClassName = TEXT_WIN_CLASS_NAME; + + class_shadow = class_main; + class_shadow.lpfnWndProc = WINHELP_ShadowWndProc; + class_shadow.hbrBackground = GetStockObject(GRAY_BRUSH); + class_shadow.lpszClassName = SHADOW_WIN_CLASS_NAME; + + class_history = class_main; + class_history.lpfnWndProc = WINHELP_HistoryWndProc; + class_history.lpszClassName = HISTORY_WIN_CLASS_NAME; + + return (RegisterClass(&class_main) && + RegisterClass(&class_button_box) && + RegisterClass(&class_text) && + RegisterClass(&class_shadow) && + RegisterClass(&class_history)); +} + +typedef struct +{ + WORD size; + WORD command; + LONG data; + LONG reserved; + WORD ofsFilename; + WORD ofsData; +} WINHELP,*LPWINHELP; + +/****************************************************************** + * WINHELP_HandleCommand + * + * + */ +static LRESULT WINHELP_HandleCommand(HWND hSrcWnd, LPARAM lParam) +{ + COPYDATASTRUCT* cds = (COPYDATASTRUCT*)lParam; + WINHELP* wh; + + if (cds->dwData != 0xA1DE505) + { + WINE_FIXME("Wrong magic number (%08lx)\n", cds->dwData); + return 0; + } + + wh = (WINHELP*)cds->lpData; + + if (wh) + { + char* ptr = (wh->ofsFilename) ? (LPSTR)wh + wh->ofsFilename : NULL; + + WINE_TRACE("Got[%u]: cmd=%u data=%08x fn=%s\n", + wh->size, wh->command, wh->data, ptr); + switch (wh->command) + { + case HELP_CONTEXT: + if (ptr) + { + MACRO_JumpContext(ptr, "main", wh->data); + } + break; + case HELP_QUIT: + MACRO_Exit(); + break; + case HELP_CONTENTS: + if (ptr) + { + MACRO_JumpContents(ptr, "main"); + } + break; + case HELP_HELPONHELP: + MACRO_HelpOn(); + break; + /* case HELP_SETINDEX: */ + case HELP_SETCONTENTS: + if (ptr) + { + MACRO_SetContents(ptr, wh->data); + } + break; + case HELP_CONTEXTPOPUP: + if (ptr) + { + MACRO_PopupContext(ptr, wh->data); + } + break; + /* case HELP_FORCEFILE:*/ + /* case HELP_CONTEXTMENU: */ + case HELP_FINDER: + /* in fact, should be the topic dialog box */ + WINE_FIXME("HELP_FINDER: stub\n"); + if (ptr) + { + MACRO_JumpHash(ptr, "main", 0); + } + break; + /* case HELP_WM_HELP: */ + /* case HELP_SETPOPUP_POS: */ + /* case HELP_KEY: */ + /* case HELP_COMMAND: */ + /* case HELP_PARTIALKEY: */ + /* case HELP_MULTIKEY: */ + /* case HELP_SETWINPOS: */ + WINE_FIXME("Unknown command (%x) for remote winhelp control\n", wh->command); + break; + } + } + return 0L; +} + +/****************************************************************** + * WINHELP_ReuseWindow + * + * + */ +static BOOL WINHELP_ReuseWindow(WINHELP_WINDOW* win, WINHELP_WINDOW* oldwin, + HLPFILE_PAGE* page, int nCmdShow) +{ + unsigned int i; + + win->hMainWnd = oldwin->hMainWnd; + win->hButtonBoxWnd = oldwin->hButtonBoxWnd; + win->hTextWnd = oldwin->hTextWnd; + win->hHistoryWnd = oldwin->hHistoryWnd; + oldwin->hMainWnd = oldwin->hButtonBoxWnd = oldwin->hTextWnd = oldwin->hHistoryWnd = 0; + win->hBrush = oldwin->hBrush; + + SetWindowLong(win->hMainWnd, 0, (LONG)win); + SetWindowLong(win->hButtonBoxWnd, 0, (LONG)win); + SetWindowLong(win->hTextWnd, 0, (LONG)win); + SetWindowLong(win->hHistoryWnd, 0, (LONG)win); + + WINHELP_InitFonts(win->hMainWnd); + + if (page) + SetWindowText(win->hMainWnd, page->file->lpszTitle); + + WINHELP_SetupText(win->hTextWnd); + InvalidateRect(win->hTextWnd, NULL, TRUE); + SendMessage(win->hMainWnd, WM_USER, 0, 0); + ShowWindow(win->hMainWnd, nCmdShow); + UpdateWindow(win->hTextWnd); + + if (!(win->info->win_style & WS_POPUP)) + { + unsigned num; + + memcpy(win->history, oldwin->history, sizeof(win->history)); + win->histIndex = oldwin->histIndex; + + /* FIXME: when using back, we shouldn't update the history... */ + + if (page) + { + for (i = 0; i < win->histIndex; i++) + if (win->history[i] == page) break; + + /* if the new page is already in the history, do nothing */ + if (i == win->histIndex) + { + num = sizeof(win->history) / sizeof(win->history[0]); + if (win->histIndex == num) + { + /* we're full, remove latest entry */ + HLPFILE_FreeHlpFile(win->history[0]->file); + memmove(&win->history[0], &win->history[1], + (num - 1) * sizeof(win->history[0])); + win->histIndex--; + } + win->history[win->histIndex++] = page; + page->file->wRefCount++; + if (win->hHistoryWnd) InvalidateRect(win->hHistoryWnd, NULL, TRUE); + } + } + + memcpy(win->back, oldwin->back, sizeof(win->back)); + win->backIndex = oldwin->backIndex; + + if (page) + { + num = sizeof(win->back) / sizeof(win->back[0]); + if (win->backIndex == num) + { + /* we're full, remove latest entry */ + HLPFILE_FreeHlpFile(win->back[0]->file); + memmove(&win->back[0], &win->back[1], + (num - 1) * sizeof(win->back[0])); + win->backIndex--; + } + win->back[win->backIndex++] = page; + page->file->wRefCount++; + } + } + else + win->backIndex = win->histIndex = 0; + + oldwin->histIndex = oldwin->backIndex = 0; + WINHELP_DeleteWindow(oldwin); + return TRUE; +} + +/*********************************************************************** + * + * WINHELP_CreateHelpWindow + */ +BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE* page, HLPFILE_WINDOWINFO* wi, + int nCmdShow) +{ + WINHELP_WINDOW *win, *oldwin; + HWND hWnd; + BOOL bPrimary; + BOOL bPopup; + LPSTR name; + + bPrimary = !lstrcmpi(wi->name, "main"); + bPopup = wi->win_style & WS_POPUP; + + /* Initialize WINHELP_WINDOW struct */ + win = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, + sizeof(WINHELP_WINDOW) + strlen(wi->name) + 1); + if (!win) return FALSE; + + win->next = Globals.win_list; + Globals.win_list = win; + + name = (char*)win + sizeof(WINHELP_WINDOW); + lstrcpy(name, wi->name); + win->lpszName = name; + + win->page = page; + + win->hArrowCur = LoadCursorA(0, (LPSTR)IDC_ARROW); + win->hHandCur = LoadCursorA(0, (LPSTR)IDC_HAND); + + win->info = wi; + + Globals.active_win = win; + + /* Initialize default pushbuttons */ + if (bPrimary && page) + { + CHAR buffer[MAX_STRING_LEN]; + + LoadString(Globals.hInstance, STID_CONTENTS, buffer, sizeof(buffer)); + MACRO_CreateButton("BTN_CONTENTS", buffer, "Contents()"); + LoadString(Globals.hInstance, STID_SEARCH,buffer, sizeof(buffer)); + MACRO_CreateButton("BTN_SEARCH", buffer, "Search()"); + LoadString(Globals.hInstance, STID_BACK, buffer, sizeof(buffer)); + MACRO_CreateButton("BTN_BACK", buffer, "Back()"); + LoadString(Globals.hInstance, STID_HISTORY, buffer, sizeof(buffer)); + MACRO_CreateButton("BTN_HISTORY", buffer, "History()"); + LoadString(Globals.hInstance, STID_TOPICS, buffer, sizeof(buffer)); + MACRO_CreateButton("BTN_TOPICS", buffer, "Finder()"); + } + + /* Initialize file specific pushbuttons */ + if (!(wi->win_style & WS_POPUP) && page) + { + HLPFILE_MACRO *macro; + for (macro = page->file->first_macro; macro; macro = macro->next) + MACRO_ExecuteMacro(macro->lpszMacro); + + for (macro = page->first_macro; macro; macro = macro->next) + MACRO_ExecuteMacro(macro->lpszMacro); + } + + /* Reuse existing window */ + if (!bPopup) + { + for (oldwin = win->next; oldwin; oldwin = oldwin->next) + { + if (!lstrcmpi(oldwin->lpszName, wi->name)) + { + return WINHELP_ReuseWindow(win, oldwin, page, nCmdShow); + } + } + if (page) + { + win->histIndex = win->backIndex = 1; + win->history[0] = win->back[0] = page; + page->file->wRefCount += 2; + strcpy(wi->caption, page->file->lpszTitle); + } + } + + hWnd = CreateWindow(bPopup ? TEXT_WIN_CLASS_NAME : MAIN_WIN_CLASS_NAME, + wi->caption, + bPrimary ? WS_OVERLAPPEDWINDOW : wi->win_style, + wi->origin.x, wi->origin.y, wi->size.cx, wi->size.cy, + NULL, bPrimary ? LoadMenu(Globals.hInstance, MAKEINTRESOURCE(MAIN_MENU)) : 0, + Globals.hInstance, win); + + ShowWindow(hWnd, nCmdShow); + UpdateWindow(hWnd); + + return TRUE; +} + +/*********************************************************************** + * + * WINHELP_CreateHelpWindowByHash + */ +BOOL WINHELP_CreateHelpWindowByHash(HLPFILE* hlpfile, LONG lHash, + HLPFILE_WINDOWINFO* wi, int nCmdShow) +{ + HLPFILE_PAGE* page = NULL; + + if (hlpfile) + page = lHash ? HLPFILE_PageByHash(hlpfile, lHash) : + HLPFILE_Contents(hlpfile); + if (page) page->file->wRefCount++; + return WINHELP_CreateHelpWindow(page, wi, nCmdShow); +} + +/*********************************************************************** + * + * WINHELP_CreateHelpWindowByMap + */ +BOOL WINHELP_CreateHelpWindowByMap(HLPFILE* hlpfile, LONG lMap, + HLPFILE_WINDOWINFO* wi, int nCmdShow) +{ + HLPFILE_PAGE* page = NULL; + + page = HLPFILE_PageByMap(hlpfile, lMap); + if (page) page->file->wRefCount++; + return WINHELP_CreateHelpWindow(page, wi, nCmdShow); +} + +/*********************************************************************** + * + * WINHELP_MainWndProc + */ +static LRESULT CALLBACK WINHELP_MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WINHELP_WINDOW *win; + WINHELP_BUTTON *button; + RECT rect, button_box_rect; + INT text_top, curPos, min, max, dy, keyDelta; + + WINHELP_CheckPopup(msg); + + switch (msg) + { + case WM_NCCREATE: + win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams; + SetWindowLong(hWnd, 0, (LONG) win); + win->hMainWnd = hWnd; + break; + + case WM_CREATE: + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + + /* Create button box and text Window */ + CreateWindow(BUTTON_BOX_WIN_CLASS_NAME, "", WS_CHILD | WS_VISIBLE, + 0, 0, 0, 0, hWnd, 0, Globals.hInstance, win); + + CreateWindow(TEXT_WIN_CLASS_NAME, "", WS_CHILD | WS_VISIBLE, + 0, 0, 0, 0, hWnd, 0, Globals.hInstance, win); + + /* Fall through */ + case WM_USER: + case WM_WINDOWPOSCHANGED: + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + GetClientRect(hWnd, &rect); + + /* Update button box and text Window */ + SetWindowPos(win->hButtonBoxWnd, HWND_TOP, + rect.left, rect.top, + rect.right - rect.left, + rect.bottom - rect.top, 0); + + GetWindowRect(win->hButtonBoxWnd, &button_box_rect); + text_top = rect.top + button_box_rect.bottom - button_box_rect.top; + + SetWindowPos(win->hTextWnd, HWND_TOP, + rect.left, text_top, + rect.right - rect.left, + rect.bottom - text_top, 0); + + break; + + case WM_COMMAND: + Globals.active_win = win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + switch (wParam) + { + /* Menu FILE */ + case MNID_FILE_OPEN: MACRO_FileOpen(); break; + case MNID_FILE_PRINT: MACRO_Print(); break; + case MNID_FILE_SETUP: MACRO_PrinterSetup(); break; + case MNID_FILE_EXIT: MACRO_Exit(); break; + + /* Menu EDIT */ + case MNID_EDIT_COPYDLG: MACRO_CopyDialog(); break; + case MNID_EDIT_ANNOTATE:MACRO_Annotate(); break; + + /* Menu Bookmark */ + case MNID_BKMK_DEFINE: MACRO_BookmarkDefine(); break; + + /* Menu Help */ + case MNID_HELP_HELPON: MACRO_HelpOn(); break; + case MNID_HELP_HELPTOP: MACRO_HelpOnTop(); break; + case MNID_HELP_ABOUT: MACRO_About(); break; + case MNID_HELP_WINE: ShellAbout(hWnd, "WINE", "Help", 0); break; + + default: + /* Buttons */ + for (button = win->first_button; button; button = button->next) + if (wParam == button->wParam) break; + if (button) + MACRO_ExecuteMacro(button->lpszMacro); + else + WINHELP_MessageBoxIDS(STID_NOT_IMPLEMENTED, 0x121, MB_OK); + break; + } + break; + case WM_DESTROY: + if (Globals.hPopupWnd) DestroyWindow(Globals.hPopupWnd); + break; + case WM_COPYDATA: + return WINHELP_HandleCommand((HWND)wParam, lParam); + + case WM_KEYDOWN: + keyDelta = 0; + + switch (wParam) + { + case VK_UP: + case VK_DOWN: + keyDelta = GetSystemMetrics(SM_CXVSCROLL); + if (wParam == VK_UP) + keyDelta = -keyDelta; + + case VK_PRIOR: + case VK_NEXT: + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + curPos = GetScrollPos(win->hTextWnd, SB_VERT); + GetScrollRange(win->hTextWnd, SB_VERT, &min, &max); + + if (keyDelta == 0) + { + GetClientRect(win->hTextWnd, &rect); + keyDelta = (rect.bottom - rect.top) / 2; + if (wParam == VK_PRIOR) + keyDelta = -keyDelta; + } + + curPos += keyDelta; + if (curPos > max) + curPos = max; + else if (curPos < min) + curPos = min; + + dy = GetScrollPos(win->hTextWnd, SB_VERT) - curPos; + SetScrollPos(win->hTextWnd, SB_VERT, curPos, TRUE); + ScrollWindow(win->hTextWnd, 0, dy, NULL, NULL); + UpdateWindow(win->hTextWnd); + return 0; + + case VK_ESCAPE: + MACRO_Exit(); + return 0; + } + break; + } + return DefWindowProc(hWnd, msg, wParam, lParam); +} + +/*********************************************************************** + * + * WINHELP_ButtonBoxWndProc + */ +static LRESULT CALLBACK WINHELP_ButtonBoxWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WINDOWPOS *winpos; + WINHELP_WINDOW *win; + WINHELP_BUTTON *button; + SIZE button_size; + INT x, y; + + WINHELP_CheckPopup(msg); + + switch (msg) + { + case WM_NCCREATE: + win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams; + SetWindowLong(hWnd, 0, (LONG) win); + win->hButtonBoxWnd = hWnd; + break; + + case WM_WINDOWPOSCHANGING: + winpos = (WINDOWPOS*) lParam; + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + + /* Update buttons */ + button_size.cx = 0; + button_size.cy = 0; + for (button = win->first_button; button; button = button->next) + { + HDC hDc; + SIZE textsize; + if (!button->hWnd) + { + button->hWnd = CreateWindow(STRING_BUTTON, button->lpszName, + WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON, + 0, 0, 0, 0, + hWnd, (HMENU) button->wParam, + Globals.hInstance, 0); + if (button->hWnd) { + if (Globals.button_proc == NULL) + Globals.button_proc = (WNDPROC) GetWindowLongPtr(button->hWnd, GWLP_WNDPROC); + SetWindowLongPtr(button->hWnd, GWLP_WNDPROC, (LONG_PTR) WINHELP_ButtonWndProc); + } + } + hDc = GetDC(button->hWnd); + GetTextExtentPoint(hDc, button->lpszName, + lstrlen(button->lpszName), &textsize); + ReleaseDC(button->hWnd, hDc); + + button_size.cx = max(button_size.cx, textsize.cx + BUTTON_CX); + button_size.cy = max(button_size.cy, textsize.cy + BUTTON_CY); + } + + x = 0; + y = 0; + for (button = win->first_button; button; button = button->next) + { + SetWindowPos(button->hWnd, HWND_TOP, x, y, button_size.cx, button_size.cy, 0); + + if (x + 2 * button_size.cx <= winpos->cx) + x += button_size.cx; + else + x = 0, y += button_size.cy; + } + winpos->cy = y + (x ? button_size.cy : 0); + break; + + case WM_COMMAND: + SendMessage(GetParent(hWnd), msg, wParam, lParam); + break; + + case WM_KEYDOWN: + switch (wParam) + { + case VK_UP: + case VK_DOWN: + case VK_PRIOR: + case VK_NEXT: + case VK_ESCAPE: + return SendMessage(GetParent(hWnd), msg, wParam, lParam); + } + break; + } + + return DefWindowProc(hWnd, msg, wParam, lParam); +} + +/*********************************************************************** + * + * WINHELP_ButtonWndProc + */ +static LRESULT CALLBACK WINHELP_ButtonWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (msg == WM_KEYDOWN) + { + switch (wParam) + { + case VK_UP: + case VK_DOWN: + case VK_PRIOR: + case VK_NEXT: + case VK_ESCAPE: + return SendMessage(GetParent(hWnd), msg, wParam, lParam); + } + } + + return CallWindowProc(Globals.button_proc, hWnd, msg, wParam, lParam); +} + +/*********************************************************************** + * + * WINHELP_TextWndProc + */ +static LRESULT CALLBACK WINHELP_TextWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WINHELP_WINDOW *win; + WINHELP_LINE *line; + WINHELP_LINE_PART *part; + WINDOWPOS *winpos; + PAINTSTRUCT ps; + HDC hDc; + POINT mouse; + INT scroll_pos; + HWND hPopupWnd; + BOOL bExit; + + if (msg != WM_LBUTTONDOWN) + WINHELP_CheckPopup(msg); + + switch (msg) + { + case WM_NCCREATE: + win = (WINHELP_WINDOW*) ((LPCREATESTRUCT) lParam)->lpCreateParams; + SetWindowLong(hWnd, 0, (LONG) win); + win->hTextWnd = hWnd; + win->hBrush = CreateSolidBrush(win->info->sr_color); + if (win->info->win_style & WS_POPUP) Globals.hPopupWnd = win->hMainWnd = hWnd; + WINHELP_InitFonts(hWnd); + break; + + case WM_CREATE: + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + + /* Calculate vertical size and position of a popup window */ + if (win->info->win_style & WS_POPUP) + { + POINT origin; + RECT old_window_rect; + RECT old_client_rect; + SIZE old_window_size; + SIZE old_client_size; + SIZE new_client_size; + SIZE new_window_size; + + GetWindowRect(hWnd, &old_window_rect); + origin.x = old_window_rect.left; + origin.y = old_window_rect.top; + old_window_size.cx = old_window_rect.right - old_window_rect.left; + old_window_size.cy = old_window_rect.bottom - old_window_rect.top; + + GetClientRect(hWnd, &old_client_rect); + old_client_size.cx = old_client_rect.right - old_client_rect.left; + old_client_size.cy = old_client_rect.bottom - old_client_rect.top; + + new_client_size = old_client_size; + WINHELP_SplitLines(hWnd, &new_client_size); + + if (origin.y + POPUP_YDISTANCE + new_client_size.cy <= GetSystemMetrics(SM_CYSCREEN)) + origin.y += POPUP_YDISTANCE; + else + origin.y -= POPUP_YDISTANCE + new_client_size.cy; + + new_window_size.cx = old_window_size.cx - old_client_size.cx + new_client_size.cx; + new_window_size.cy = old_window_size.cy - old_client_size.cy + new_client_size.cy; + + win->hShadowWnd = + CreateWindow(SHADOW_WIN_CLASS_NAME, "", WS_POPUP, + origin.x + SHADOW_DX, origin.y + SHADOW_DY, + new_window_size.cx, new_window_size.cy, + 0, 0, Globals.hInstance, 0); + + SetWindowPos(hWnd, HWND_TOP, origin.x, origin.y, + new_window_size.cx, new_window_size.cy, + 0); + SetWindowPos(win->hShadowWnd, hWnd, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE); + ShowWindow(win->hShadowWnd, SW_NORMAL); + SetActiveWindow(hWnd); + } + break; + + case WM_WINDOWPOSCHANGED: + winpos = (WINDOWPOS*) lParam; + + if (!(winpos->flags & SWP_NOSIZE)) WINHELP_SetupText(hWnd); + break; + + case WM_MOUSEWHEEL: + { + int wheelDelta = 0; + UINT scrollLines = 3; + int curPos = GetScrollPos(hWnd, SB_VERT); + int min, max; + + GetScrollRange(hWnd, SB_VERT, &min, &max); + + SystemParametersInfo(SPI_GETWHEELSCROLLLINES,0, &scrollLines, 0); + if (wParam & (MK_SHIFT | MK_CONTROL)) + return DefWindowProc(hWnd, msg, wParam, lParam); + wheelDelta -= GET_WHEEL_DELTA_WPARAM(wParam); + if (abs(wheelDelta) >= WHEEL_DELTA && scrollLines) { + int dy; + + curPos += wheelDelta; + if (curPos > max) + curPos = max; + else if (curPos < min) + curPos = min; + + dy = GetScrollPos(hWnd, SB_VERT) - curPos; + SetScrollPos(hWnd, SB_VERT, curPos, TRUE); + ScrollWindow(hWnd, 0, dy, NULL, NULL); + UpdateWindow(hWnd); + } + } + break; + + case WM_VSCROLL: + { + BOOL update = TRUE; + RECT rect; + INT Min, Max; + INT CurPos = GetScrollPos(hWnd, SB_VERT); + INT dy; + + GetScrollRange(hWnd, SB_VERT, &Min, &Max); + GetClientRect(hWnd, &rect); + + switch (wParam & 0xffff) + { + case SB_THUMBTRACK: + case SB_THUMBPOSITION: CurPos = wParam >> 16; break; + case SB_TOP: CurPos = Min; break; + case SB_BOTTOM: CurPos = Max; break; + case SB_PAGEUP: CurPos -= (rect.bottom - rect.top) / 2; break; + case SB_PAGEDOWN: CurPos += (rect.bottom - rect.top) / 2; break; + case SB_LINEUP: CurPos -= GetSystemMetrics(SM_CXVSCROLL); break; + case SB_LINEDOWN: CurPos += GetSystemMetrics(SM_CXVSCROLL); break; + default: update = FALSE; + } + if (update) + { + if (CurPos > Max) + CurPos = Max; + else if (CurPos < Min) + CurPos = Min; + dy = GetScrollPos(hWnd, SB_VERT) - CurPos; + SetScrollPos(hWnd, SB_VERT, CurPos, TRUE); + ScrollWindow(hWnd, 0, dy, NULL, NULL); + UpdateWindow(hWnd); + } + } + break; + + case WM_PAINT: + hDc = BeginPaint(hWnd, &ps); + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + scroll_pos = GetScrollPos(hWnd, SB_VERT); + + /* No DPtoLP needed - MM_TEXT map mode */ + if (ps.fErase) FillRect(hDc, &ps.rcPaint, win->hBrush); + for (line = win->first_line; line; line = line->next) + { + for (part = &line->first_part; part; part = part->next) + { + switch (part->cookie) + { + case hlp_line_part_text: + SelectObject(hDc, part->u.text.hFont); + SetTextColor(hDc, part->u.text.color); + SetBkColor(hDc, win->info->sr_color); + TextOut(hDc, part->rect.left, part->rect.top - scroll_pos, + part->u.text.lpsText, part->u.text.wTextLen); + if (part->u.text.wUnderline) + { + HPEN hPen; + + switch (part->u.text.wUnderline) + { + case 1: /* simple */ + case 2: /* double */ + hPen = CreatePen(PS_SOLID, 1, part->u.text.color); + break; + case 3: /* dotted */ + hPen = CreatePen(PS_DOT, 1, part->u.text.color); + break; + default: + WINE_FIXME("Unknow underline type\n"); + continue; + } + + SelectObject(hDc, hPen); + MoveToEx(hDc, part->rect.left, part->rect.bottom - scroll_pos - 1, NULL); + LineTo(hDc, part->rect.right, part->rect.bottom - scroll_pos - 1); + if (part->u.text.wUnderline == 2) + { + MoveToEx(hDc, part->rect.left, part->rect.bottom - scroll_pos + 1, NULL); + LineTo(hDc, part->rect.right, part->rect.bottom - scroll_pos + 1); + } + DeleteObject(hPen); + } + break; + case hlp_line_part_bitmap: + { + HDC hMemDC; + + hMemDC = CreateCompatibleDC(hDc); + SelectObject(hMemDC, part->u.bitmap.hBitmap); + BitBlt(hDc, part->rect.left, part->rect.top - scroll_pos, + part->rect.right - part->rect.left, part->rect.bottom - part->rect.top, + hMemDC, 0, 0, SRCCOPY); + DeleteDC(hMemDC); + } + break; + case hlp_line_part_metafile: + { + HDC hMemDC; + HBITMAP hBitmap; + SIZE sz; + RECT rc; + + sz.cx = part->rect.right - part->rect.left; + sz.cy = part->rect.bottom - part->rect.top; + hMemDC = CreateCompatibleDC(hDc); + hBitmap = CreateCompatibleBitmap(hDc, sz.cx, sz.cy); + SelectObject(hMemDC, hBitmap); + SelectObject(hMemDC, win->hBrush); + rc.left = 0; + rc.top = 0; + rc.right = sz.cx; + rc.bottom = sz.cy; + FillRect(hMemDC, &rc, win->hBrush); + SetMapMode(hMemDC, part->u.metafile.mm); + SetWindowExtEx(hMemDC, sz.cx, sz.cy, 0); + SetViewportExtEx(hMemDC, sz.cx, sz.cy, 0); + SetWindowOrgEx(hMemDC, 0, 0, 0); + SetViewportOrgEx(hMemDC, 0, 0, 0); + PlayMetaFile(hMemDC, part->u.metafile.hMetaFile); + SetMapMode(hMemDC, MM_TEXT); + SetWindowOrgEx(hMemDC, 0, 0, 0); + SetViewportOrgEx(hMemDC, 0, 0, 0); + BitBlt(hDc, part->rect.left, part->rect.top - scroll_pos, + sz.cx, sz.cy, hMemDC, 0, 0, SRCCOPY); + DeleteDC(hMemDC); + DeleteObject(hBitmap); + } + break; + } + } + } + + EndPaint(hWnd, &ps); + break; + + case WM_MOUSEMOVE: + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + + if (WINHELP_IsOverLink(win, wParam, lParam)) + SetCursor(win->hHandCur); /* set to hand pointer cursor to indicate a link */ + else + SetCursor(win->hArrowCur); /* set to hand pointer cursor to indicate a link */ + + break; + + case WM_LBUTTONDOWN: + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + + hPopupWnd = Globals.hPopupWnd; + Globals.hPopupWnd = 0; + + part = WINHELP_IsOverLink(win, wParam, lParam); + if (part) + { + HLPFILE* hlpfile; + HLPFILE_WINDOWINFO* wi; + + mouse.x = (short)LOWORD(lParam); + mouse.y = (short)HIWORD(lParam); + + if (part->link) switch (part->link->cookie) + { + case hlp_link_link: + hlpfile = WINHELP_LookupHelpFile(part->link->lpszString); + if (part->link->window == -1) + wi = win->info; + else if ((part->link->window >= 0) && (part->link->window < hlpfile->numWindows)) + wi = &hlpfile->windows[part->link->window]; + else + { + WINE_WARN("link to window %d/%d\n", part->link->window, hlpfile->numWindows); + break; + } + WINHELP_CreateHelpWindowByHash(hlpfile, part->link->lHash, wi, + SW_NORMAL); + break; + case hlp_link_popup: + hlpfile = WINHELP_LookupHelpFile(part->link->lpszString); + if (hlpfile) WINHELP_CreateHelpWindowByHash(hlpfile, part->link->lHash, + WINHELP_GetPopupWindowInfo(hlpfile, hWnd, &mouse), + SW_NORMAL); + break; + case hlp_link_macro: + MACRO_ExecuteMacro(part->link->lpszString); + break; + default: + WINE_FIXME("Unknown link cookie %d\n", part->link->cookie); + } + } + + if (hPopupWnd) + DestroyWindow(hPopupWnd); + break; + + case WM_NCDESTROY: + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + + if (hWnd == Globals.hPopupWnd) Globals.hPopupWnd = 0; + + bExit = (Globals.wVersion >= 4 && !lstrcmpi(win->lpszName, "main")); + DeleteObject(win->hBrush); + + WINHELP_DeleteWindow(win); + + if (bExit) MACRO_Exit(); + + if (!Globals.win_list) + PostQuitMessage(0); + break; + } + + return DefWindowProc(hWnd, msg, wParam, lParam); +} + +/****************************************************************** + * WINHELP_HistoryWndProc + * + * + */ +static LRESULT CALLBACK WINHELP_HistoryWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WINHELP_WINDOW* win; + PAINTSTRUCT ps; + HDC hDc; + TEXTMETRIC tm; + unsigned int i; + RECT r; + + switch (msg) + { + case WM_NCCREATE: + win = (WINHELP_WINDOW*)((LPCREATESTRUCT)lParam)->lpCreateParams; + SetWindowLong(hWnd, 0, (LONG)win); + win->hHistoryWnd = hWnd; + break; + case WM_CREATE: + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + hDc = GetDC(hWnd); + GetTextMetrics(hDc, &tm); + GetWindowRect(hWnd, &r); + + r.right = r.left + 30 * tm.tmAveCharWidth; + r.bottom = r.top + (sizeof(win->history) / sizeof(win->history[0])) * tm.tmHeight; + AdjustWindowRect(&r, GetWindowLong(hWnd, GWL_STYLE), FALSE); + if (r.left < 0) {r.right -= r.left; r.left = 0;} + if (r.top < 0) {r.bottom -= r.top; r.top = 0;} + + MoveWindow(hWnd, r.left, r.top, r.right, r.bottom, TRUE); + ReleaseDC(hWnd, hDc); + break; + case WM_LBUTTONDOWN: + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + hDc = GetDC(hWnd); + GetTextMetrics(hDc, &tm); + i = HIWORD(lParam) / tm.tmHeight; + if (i < win->histIndex) + WINHELP_CreateHelpWindow(win->history[i], win->info, SW_SHOW); + ReleaseDC(hWnd, hDc); + break; + case WM_PAINT: + hDc = BeginPaint(hWnd, &ps); + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + GetTextMetrics(hDc, &tm); + + for (i = 0; i < win->histIndex; i++) + { + TextOut(hDc, 0, i * tm.tmHeight, win->history[i]->lpszTitle, + strlen(win->history[i]->lpszTitle)); + } + EndPaint(hWnd, &ps); + break; + case WM_DESTROY: + win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + if (hWnd == win->hHistoryWnd) + win->hHistoryWnd = 0; + break; + } + return DefWindowProc(hWnd, msg, wParam, lParam); +} + +/*********************************************************************** + * + * WINHELP_ShadowWndProc + */ +static LRESULT CALLBACK WINHELP_ShadowWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + WINHELP_CheckPopup(msg); + return DefWindowProc(hWnd, msg, wParam, lParam); +} + +/*********************************************************************** + * + * SetupText + */ +static void WINHELP_SetupText(HWND hWnd) +{ + HDC hDc = GetDC(hWnd); + RECT rect; + SIZE newsize; + + ShowScrollBar(hWnd, SB_VERT, FALSE); + if (!WINHELP_SplitLines(hWnd, NULL)) + { + ShowScrollBar(hWnd, SB_VERT, TRUE); + GetClientRect(hWnd, &rect); + + WINHELP_SplitLines(hWnd, &newsize); + SetScrollRange(hWnd, SB_VERT, 0, rect.top + newsize.cy - rect.bottom, TRUE); + } + else + { + SetScrollPos(hWnd, SB_VERT, 0, FALSE); + SetScrollRange(hWnd, SB_VERT, 0, 0, FALSE); + } + + ReleaseDC(hWnd, hDc); +} + +/*********************************************************************** + * + * WINHELP_AppendText + */ +static BOOL WINHELP_AppendText(WINHELP_LINE ***linep, WINHELP_LINE_PART ***partp, + LPSIZE space, LPSIZE textsize, + INT *line_ascent, INT ascent, + LPCSTR text, UINT textlen, + HFONT font, COLORREF color, HLPFILE_LINK *link, + unsigned underline) +{ + WINHELP_LINE *line; + WINHELP_LINE_PART *part; + LPSTR ptr; + + if (!*partp) /* New line */ + { + *line_ascent = ascent; + + line = HeapAlloc(GetProcessHeap(), 0, + sizeof(WINHELP_LINE) + textlen); + if (!line) return FALSE; + + line->next = 0; + part = &line->first_part; + ptr = (char*)line + sizeof(WINHELP_LINE); + + line->rect.top = (**linep ? (**linep)->rect.bottom : 0) + space->cy; + line->rect.bottom = line->rect.top; + line->rect.left = space->cx; + line->rect.right = space->cx; + + if (**linep) *linep = &(**linep)->next; + **linep = line; + space->cy = 0; + } + else /* Same line */ + { + line = **linep; + + if (*line_ascent < ascent) + { + WINHELP_LINE_PART *p; + for (p = &line->first_part; p; p = p->next) + { + p->rect.top += ascent - *line_ascent; + p->rect.bottom += ascent - *line_ascent; + } + line->rect.bottom += ascent - *line_ascent; + *line_ascent = ascent; + } + + part = HeapAlloc(GetProcessHeap(), 0, + sizeof(WINHELP_LINE_PART) + textlen); + if (!part) return FALSE; + **partp = part; + ptr = (char*)part + sizeof(WINHELP_LINE_PART); + } + + memcpy(ptr, text, textlen); + part->cookie = hlp_line_part_text; + part->rect.left = line->rect.right + (*partp ? space->cx : 0); + part->rect.right = part->rect.left + textsize->cx; + line->rect.right = part->rect.right; + part->rect.top = + ((*partp) ? line->rect.top : line->rect.bottom) + *line_ascent - ascent; + part->rect.bottom = part->rect.top + textsize->cy; + line->rect.bottom = max(line->rect.bottom, part->rect.bottom); + part->u.text.lpsText = ptr; + part->u.text.wTextLen = textlen; + part->u.text.hFont = font; + part->u.text.color = color; + part->u.text.wUnderline = underline; + + WINE_TRACE("Appended text '%*.*s'[%d] @ (%d,%d-%d,%d)\n", + part->u.text.wTextLen, + part->u.text.wTextLen, + part->u.text.lpsText, + part->u.text.wTextLen, + part->rect.left, part->rect.top, part->rect.right, part->rect.bottom); + + part->link = link; + if (link) link->wRefCount++; + + part->next = 0; + *partp = &part->next; + + space->cx = 0; + + return TRUE; +} + +/*********************************************************************** + * + * WINHELP_AppendGfxObject + */ +static WINHELP_LINE_PART* WINHELP_AppendGfxObject(WINHELP_LINE ***linep, WINHELP_LINE_PART ***partp, + LPSIZE space, LPSIZE gfxSize, + HLPFILE_LINK *link, unsigned pos) +{ + WINHELP_LINE *line; + WINHELP_LINE_PART *part; + LPSTR ptr; + + if (!*partp || pos == 1) /* New line */ + { + line = HeapAlloc(GetProcessHeap(), 0, sizeof(WINHELP_LINE)); + if (!line) return NULL; + + line->next = NULL; + part = &line->first_part; + + line->rect.top = (**linep ? (**linep)->rect.bottom : 0) + space->cy; + line->rect.bottom = line->rect.top; + line->rect.left = space->cx; + line->rect.right = space->cx; + + if (**linep) *linep = &(**linep)->next; + **linep = line; + space->cy = 0; + ptr = (char*)line + sizeof(WINHELP_LINE); + } + else /* Same line */ + { + if (pos == 2) WINE_FIXME("Left alignment not handled\n"); + line = **linep; + + part = HeapAlloc(GetProcessHeap(), 0, sizeof(WINHELP_LINE_PART)); + if (!part) return NULL; + **partp = part; + ptr = (char*)part + sizeof(WINHELP_LINE_PART); + } + + /* part->cookie should be set by caller (image or metafile) */ + part->rect.left = line->rect.right + (*partp ? space->cx : 0); + part->rect.right = part->rect.left + gfxSize->cx; + line->rect.right = part->rect.right; + part->rect.top = (*partp) ? line->rect.top : line->rect.bottom; + part->rect.bottom = part->rect.top + gfxSize->cy; + line->rect.bottom = max(line->rect.bottom, part->rect.bottom); + + WINE_TRACE("Appended gfx @ (%d,%d-%d,%d)\n", + part->rect.left, part->rect.top, part->rect.right, part->rect.bottom); + + part->link = link; + if (link) link->wRefCount++; + + part->next = NULL; + *partp = &part->next; + + space->cx = 0; + + return part; +} + + +/*********************************************************************** + * + * WINHELP_SplitLines + */ +static BOOL WINHELP_SplitLines(HWND hWnd, LPSIZE newsize) +{ + WINHELP_WINDOW *win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + HLPFILE_PARAGRAPH *p; + WINHELP_LINE **line = &win->first_line; + WINHELP_LINE_PART **part = 0; + INT line_ascent = 0; + SIZE space; + RECT rect; + HDC hDc; + + if (newsize) newsize->cx = newsize->cy = 0; + + if (!win->page) return TRUE; + + WINHELP_DeleteLines(win); + + GetClientRect(hWnd, &rect); + + rect.top += INTERNAL_BORDER_WIDTH; + rect.left += INTERNAL_BORDER_WIDTH; + rect.right -= INTERNAL_BORDER_WIDTH; + rect.bottom -= INTERNAL_BORDER_WIDTH; + + space.cy = rect.top; + space.cx = rect.left; + + hDc = GetDC(hWnd); + + for (p = win->page->first_paragraph; p; p = p->next) + { + switch (p->cookie) + { + case para_normal_text: + case para_debug_text: + { + TEXTMETRIC tm; + SIZE textsize = {0, 0}; + LPCSTR text = p->u.text.lpszText; + UINT indent = 0; + UINT len = strlen(text); + unsigned underline = 0; + + HFONT hFont = 0; + COLORREF color = RGB(0, 0, 0); + + if (p->u.text.wFont < win->page->file->numFonts) + { + HLPFILE* hlpfile = win->page->file; + + if (!hlpfile->fonts[p->u.text.wFont].hFont) + hlpfile->fonts[p->u.text.wFont].hFont = CreateFontIndirect(&hlpfile->fonts[p->u.text.wFont].LogFont); + hFont = hlpfile->fonts[p->u.text.wFont].hFont; + color = hlpfile->fonts[p->u.text.wFont].color; + } + else + { + UINT wFont = (p->u.text.wFont < win->fonts_len) ? p->u.text.wFont : 0; + + hFont = win->fonts[wFont]; + } + + if (p->link && p->link->bClrChange) + { + underline = (p->link->cookie == hlp_link_popup) ? 3 : 1; + color = RGB(0, 0x80, 0); + } + if (p->cookie == para_debug_text) color = RGB(0xff, 0, 0); + + SelectObject(hDc, hFont); + + GetTextMetrics(hDc, &tm); + + if (p->u.text.wIndent) + { + indent = p->u.text.wIndent * 5 * tm.tmAveCharWidth; + if (!part) + space.cx = rect.left + indent - 2 * tm.tmAveCharWidth; + } + + if (p->u.text.wVSpace) + { + part = 0; + space.cx = rect.left + indent; + space.cy += (p->u.text.wVSpace - 1) * tm.tmHeight; + } + + if (p->u.text.wHSpace) + { + space.cx += p->u.text.wHSpace * 2 * tm.tmAveCharWidth; + } + + WINE_TRACE("splitting text %s\n", text); + + while (len) + { + INT free_width = rect.right - (part ? (*line)->rect.right : rect.left) - space.cx; + UINT low = 0, curr = len, high = len, textlen = 0; + + if (free_width > 0) + { + while (1) + { + GetTextExtentPoint(hDc, text, curr, &textsize); + + if (textsize.cx <= free_width) low = curr; + else high = curr; + + if (high <= low + 1) break; + + if (textsize.cx) curr = (curr * free_width) / textsize.cx; + if (curr <= low) curr = low + 1; + else if (curr >= high) curr = high - 1; + } + textlen = low; + while (textlen && text[textlen] && text[textlen] != ' ') textlen--; + } + if (!part && !textlen) textlen = max(low, 1); + + if (free_width <= 0 || !textlen) + { + part = 0; + space.cx = rect.left + indent; + space.cx = min(space.cx, rect.right - rect.left - 1); + continue; + } + + WINE_TRACE("\t => %d %*s\n", textlen, textlen, text); + + if (!WINHELP_AppendText(&line, &part, &space, &textsize, + &line_ascent, tm.tmAscent, + text, textlen, hFont, color, p->link, underline) || + (!newsize && (*line)->rect.bottom > rect.bottom)) + { + ReleaseDC(hWnd, hDc); + return FALSE; + } + + if (newsize) + newsize->cx = max(newsize->cx, (*line)->rect.right + INTERNAL_BORDER_WIDTH); + + len -= textlen; + text += textlen; + if (text[0] == ' ') text++, len--; + } + } + break; + case para_bitmap: + case para_metafile: + { + SIZE gfxSize; + INT free_width; + WINHELP_LINE_PART* ref_part; + + if (p->u.gfx.pos & 0x8000) + { + space.cx = rect.left; + if (*line) + space.cy += (*line)->rect.bottom - (*line)->rect.top; + part = 0; + } + + if (p->cookie == para_bitmap) + { + DIBSECTION dibs; + + GetObject(p->u.gfx.u.bmp.hBitmap, sizeof(dibs), &dibs); + gfxSize.cx = dibs.dsBm.bmWidth; + gfxSize.cy = dibs.dsBm.bmHeight; + } + else + { + LPMETAFILEPICT lpmfp = &p->u.gfx.u.mfp; + if (lpmfp->mm == MM_ANISOTROPIC || lpmfp->mm == MM_ISOTROPIC) + { + gfxSize.cx = MulDiv(lpmfp->xExt, GetDeviceCaps(hDc, HORZRES), + 100*GetDeviceCaps(hDc, HORZSIZE)); + gfxSize.cy = MulDiv(lpmfp->yExt, GetDeviceCaps(hDc, VERTRES), + 100*GetDeviceCaps(hDc, VERTSIZE)); + } + else + { + gfxSize.cx = lpmfp->xExt; + gfxSize.cy = lpmfp->yExt; + } + } + + free_width = rect.right - ((part && *line) ? (*line)->rect.right : rect.left) - space.cx; + if (free_width <= 0) + { + part = NULL; + space.cx = rect.left; + space.cx = min(space.cx, rect.right - rect.left - 1); + } + ref_part = WINHELP_AppendGfxObject(&line, &part, &space, &gfxSize, + p->link, p->u.gfx.pos); + if (!ref_part || (!newsize && (*line)->rect.bottom > rect.bottom)) + { + return FALSE; + } + if (p->cookie == para_bitmap) + { + ref_part->cookie = hlp_line_part_bitmap; + ref_part->u.bitmap.hBitmap = p->u.gfx.u.bmp.hBitmap; + } + else + { + ref_part->cookie = hlp_line_part_metafile; + ref_part->u.metafile.hMetaFile = p->u.gfx.u.mfp.hMF; + ref_part->u.metafile.mm = p->u.gfx.u.mfp.mm; + } + } + break; + } + } + + if (newsize) + newsize->cy = (*line)->rect.bottom + INTERNAL_BORDER_WIDTH; + + ReleaseDC(hWnd, hDc); + return TRUE; +} + +/*********************************************************************** + * + * WINHELP_CheckPopup + */ +static void WINHELP_CheckPopup(UINT msg) +{ + if (!Globals.hPopupWnd) return; + + switch (msg) + { + case WM_COMMAND: + case WM_LBUTTONDOWN: + case WM_MBUTTONDOWN: + case WM_RBUTTONDOWN: + case WM_NCLBUTTONDOWN: + case WM_NCMBUTTONDOWN: + case WM_NCRBUTTONDOWN: + DestroyWindow(Globals.hPopupWnd); + Globals.hPopupWnd = 0; + } +} + +/*********************************************************************** + * + * WINHELP_DeleteLines + */ +static void WINHELP_DeleteLines(WINHELP_WINDOW *win) +{ + WINHELP_LINE *line, *next_line; + WINHELP_LINE_PART *part, *next_part; + for (line = win->first_line; line; line = next_line) + { + next_line = line->next; + for (part = &line->first_part; part; part = next_part) + { + next_part = part->next; + HLPFILE_FreeLink(part->link); + HeapFree(GetProcessHeap(), 0, part); + } + } + win->first_line = 0; +} + +/*********************************************************************** + * + * WINHELP_DeleteWindow + */ +static void WINHELP_DeleteWindow(WINHELP_WINDOW* win) +{ + WINHELP_WINDOW** w; + unsigned int i; + WINHELP_BUTTON* b; + WINHELP_BUTTON* bp; + + for (w = &Globals.win_list; *w; w = &(*w)->next) + { + if (*w == win) + { + *w = win->next; + break; + } + } + + if (Globals.active_win == win) + { + Globals.active_win = Globals.win_list; + if (Globals.win_list) + SetActiveWindow(Globals.win_list->hMainWnd); + } + + for (b = win->first_button; b; b = bp) + { + DestroyWindow(b->hWnd); + bp = b->next; + HeapFree(GetProcessHeap(), 0, b); + } + + if (win->hShadowWnd) DestroyWindow(win->hShadowWnd); + if (win->hHistoryWnd) DestroyWindow(win->hHistoryWnd); + + for (i = 0; i < win->histIndex; i++) + { + HLPFILE_FreeHlpFile(win->history[i]->file); + } + + for (i = 0; i < win->backIndex; i++) + HLPFILE_FreeHlpFile(win->back[i]->file); + + if (win->page) HLPFILE_FreeHlpFile(win->page->file); + WINHELP_DeleteLines(win); + HeapFree(GetProcessHeap(), 0, win); +} + +/*********************************************************************** + * + * WINHELP_InitFonts + */ +static void WINHELP_InitFonts(HWND hWnd) +{ + WINHELP_WINDOW *win = (WINHELP_WINDOW*) GetWindowLong(hWnd, 0); + LOGFONT logfontlist[] = { + {-10, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, + {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, + {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, + {-12, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, + {-12, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, + {-10, 0, 0, 0, 700, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}, + { -8, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 32, "Helv"}}; +#define FONTS_LEN (sizeof(logfontlist)/sizeof(*logfontlist)) + + static HFONT fonts[FONTS_LEN]; + static BOOL init = 0; + + win->fonts_len = FONTS_LEN; + win->fonts = fonts; + + if (!init) + { + UINT i; + + for (i = 0; i < FONTS_LEN; i++) + { + fonts[i] = CreateFontIndirect(&logfontlist[i]); + } + + init = 1; + } +} + +/*********************************************************************** + * + * WINHELP_MessageBoxIDS + */ +INT WINHELP_MessageBoxIDS(UINT ids_text, UINT ids_title, WORD type) +{ + CHAR text[MAX_STRING_LEN]; + CHAR title[MAX_STRING_LEN]; + + LoadString(Globals.hInstance, ids_text, text, sizeof(text)); + LoadString(Globals.hInstance, ids_title, title, sizeof(title)); + + return MessageBox(0, text, title, type); +} + +/*********************************************************************** + * + * MAIN_MessageBoxIDS_s + */ +INT WINHELP_MessageBoxIDS_s(UINT ids_text, LPCSTR str, UINT ids_title, WORD type) +{ + CHAR text[MAX_STRING_LEN]; + CHAR title[MAX_STRING_LEN]; + CHAR newtext[MAX_STRING_LEN + MAX_PATH]; + + LoadString(Globals.hInstance, ids_text, text, sizeof(text)); + LoadString(Globals.hInstance, ids_title, title, sizeof(title)); + wsprintf(newtext, text, str); + + return MessageBox(0, newtext, title, type); +} + +/****************************************************************** + * WINHELP_IsOverLink + * + * + */ +WINHELP_LINE_PART* WINHELP_IsOverLink(WINHELP_WINDOW* win, WPARAM wParam, LPARAM lParam) +{ + POINT mouse; + WINHELP_LINE *line; + WINHELP_LINE_PART *part; + int scroll_pos = GetScrollPos(win->hTextWnd, SB_VERT); + + mouse.x = LOWORD(lParam); + mouse.y = HIWORD(lParam); + for (line = win->first_line; line; line = line->next) + { + for (part = &line->first_part; part; part = part->next) + { + if (part->link && + part->link->lpszString && + part->rect.left <= mouse.x && + part->rect.right >= mouse.x && + part->rect.top <= mouse.y + scroll_pos && + part->rect.bottom >= mouse.y + scroll_pos) + { + return part; + } + } + } + + return NULL; +} diff --git a/reactos/base/applications/winhelp/winhelp.h b/reactos/base/applications/winhelp/winhelp.h new file mode 100644 index 00000000000..b49324c63ae --- /dev/null +++ b/reactos/base/applications/winhelp/winhelp.h @@ -0,0 +1,200 @@ +/* + * Help Viewer + * + * Copyright 1996 Ulrich Schmid + * Copyright 2002 Sylvain Petreolle + * 2002 Eric Pouech + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __WINHELP_H__ +#define __WINHELP_H__ + +#define MAX_LANGUAGE_NUMBER 255 +#define MAX_STRING_LEN 255 + +#define INTERNAL_BORDER_WIDTH 5 +#define POPUP_YDISTANCE 20 +#define SHADOW_DX 10 +#define SHADOW_DY 10 +#define BUTTON_CX 6 +#define BUTTON_CY 6 + +#define WINE_WARN DPRINT + +#ifndef RC_INVOKED + +#include + +#include "hlpfile.h" +#include "windef.h" +#include "winbase.h" +#include "macro.h" +#include "winhelp_res.h" + +typedef struct tagHelpLinePart +{ + RECT rect; + enum {hlp_line_part_text, hlp_line_part_bitmap, hlp_line_part_metafile} cookie; + union + { + struct + { + LPCSTR lpsText; + HFONT hFont; + COLORREF color; + WORD wTextLen; + WORD wUnderline; /* 0 None, 1 simple, 2 double, 3 dotted */ + } text; + struct + { + HBITMAP hBitmap; + } bitmap; + struct + { + HMETAFILE hMetaFile; + INT mm; + } metafile; + } u; + HLPFILE_LINK* link; + + struct tagHelpLinePart *next; +} WINHELP_LINE_PART; + +typedef struct tagHelpLine +{ + RECT rect; + WINHELP_LINE_PART first_part; + struct tagHelpLine* next; +} WINHELP_LINE; + +typedef struct tagHelpButton +{ + HWND hWnd; + + LPCSTR lpszID; + LPCSTR lpszName; + LPCSTR lpszMacro; + + WPARAM wParam; + + RECT rect; + + struct tagHelpButton*next; +} WINHELP_BUTTON; + +typedef struct tagWinHelp +{ + LPCSTR lpszName; + + WINHELP_BUTTON* first_button; + HLPFILE_PAGE* page; + WINHELP_LINE* first_line; + + HWND hMainWnd; + HWND hButtonBoxWnd; + HWND hTextWnd; + HWND hShadowWnd; + HWND hHistoryWnd; + + HFONT* fonts; + UINT fonts_len; + + HCURSOR hArrowCur; + HCURSOR hHandCur; + + HBRUSH hBrush; + + HLPFILE_WINDOWINFO* info; + + /* FIXME: for now it's a fixed size */ + HLPFILE_PAGE* history[40]; + unsigned histIndex; + HLPFILE_PAGE* back[40]; + unsigned backIndex; + + struct tagWinHelp* next; +} WINHELP_WINDOW; + +#define DC_NOMSG 0x00000000 +#define DC_MINMAX 0x00000001 +#define DC_INITTERM 0x00000002 +#define DC_JUMP 0x00000004 +#define DC_ACTIVATE 0x00000008 +#define DC_CALLBACKS 0x00000010 + +#define DW_NOTUSED 0 +#define DW_WHATMSG 1 +#define DW_MINMAX 2 +#define DW_SIZE 3 +#define DW_INIT 4 +#define DW_TERM 5 +#define DW_STARTJUMP 6 +#define DW_ENDJUMP 7 +#define DW_CHGFILE 8 +#define DW_ACTIVATE 9 +#define DW_CALLBACKS 10 + +typedef long (CALLBACK *WINHELP_LDLLHandler)(WORD, LONG, LONG); + +typedef struct tagDll +{ + HANDLE hLib; + const char* name; + WINHELP_LDLLHandler handler; + DWORD class; + struct tagDll* next; +} WINHELP_DLL; + +typedef struct +{ + UINT wVersion; + HANDLE hInstance; + HWND hPopupWnd; + UINT wStringTableOffset; + BOOL isBook; + WINHELP_WINDOW* active_win; + WINHELP_WINDOW* win_list; + WNDPROC button_proc; + WINHELP_DLL* dlls; +} WINHELP_GLOBALS; + +extern WINHELP_GLOBALS Globals; +extern FARPROC Callbacks[]; + +BOOL WINHELP_CreateHelpWindowByHash(HLPFILE*, LONG, HLPFILE_WINDOWINFO*, int); +BOOL WINHELP_CreateHelpWindowByMap(HLPFILE*, LONG, HLPFILE_WINDOWINFO*, int); +BOOL WINHELP_CreateHelpWindow(HLPFILE_PAGE*, HLPFILE_WINDOWINFO*, int); +BOOL WINHELP_GetOpenFileName(LPSTR, int); +INT WINHELP_MessageBoxIDS(UINT, UINT, WORD); +INT WINHELP_MessageBoxIDS_s(UINT, LPCSTR, UINT, WORD); +HLPFILE* WINHELP_LookupHelpFile(LPCSTR lpszFile); +HLPFILE_WINDOWINFO* WINHELP_GetWindowInfo(HLPFILE* hlpfile, LPCSTR name); + +extern const char MAIN_WIN_CLASS_NAME[]; +extern const char BUTTON_BOX_WIN_CLASS_NAME[]; +extern const char TEXT_WIN_CLASS_NAME[]; +extern const char SHADOW_WIN_CLASS_NAME[]; +extern const char HISTORY_WIN_CLASS_NAME[]; +extern const char STRING_BUTTON[]; +extern const char STRING_MENU_Xx[]; +extern const char STRING_DIALOG_TEST[]; +#endif + +/* Buttons */ +#define WH_FIRST_BUTTON 500 + +#endif /* __WINHELP_H__ */ diff --git a/reactos/base/applications/winhelp/winhelp.rbuild b/reactos/base/applications/winhelp/winhelp.rbuild new file mode 100644 index 00000000000..f9591c43d1f --- /dev/null +++ b/reactos/base/applications/winhelp/winhelp.rbuild @@ -0,0 +1,26 @@ + + + + . + + 0x0600 + 0x0501 + kernel32 + user32 + gdi32 + ntdll + comdlg32 + advapi32 + shell32 + comctl32 + + callback.c + hlpfile.c + macro.c + string.c + winhelp.c + lex.yy.c + + rsrc.rc + + diff --git a/reactos/base/applications/winhelp/winhelp_res.h b/reactos/base/applications/winhelp/winhelp_res.h new file mode 100644 index 00000000000..a6e46f1f127 --- /dev/null +++ b/reactos/base/applications/winhelp/winhelp_res.h @@ -0,0 +1,32 @@ +#define MNID_FILE_OPEN 0x101 +#define MNID_FILE_PRINT 0x104 +#define MNID_FILE_SETUP 0x106 +#define MNID_FILE_EXIT 0x108 + +#define MNID_EDIT_COPYDLG 0x111 +#define MNID_EDIT_ANNOTATE 0x112 + +#define MNID_BKMK_DEFINE 0x121 + +#define MNID_HELP_HELPON 0x131 +#define MNID_HELP_HELPTOP 0x132 +#define MNID_HELP_ABOUT 0x141 +#define MNID_HELP_WINE 0x142 + +#define MAIN_MENU 0x10F + +#define STID_WINE_HELP 0x120 +#define STID_WHERROR 0x121 +#define STID_WARNING 0x122 +#define STID_INFO 0x123 +#define STID_NOT_IMPLEMENTED 0x124 +#define STID_HLPFILE_ERROR_s 0x125 +#define STID_CONTENTS 0x126 +#define STID_SEARCH 0x127 +#define STID_BACK 0x128 +#define STID_HISTORY 0x129 +#define STID_TOPICS 0x12A +#define STID_ALL_FILES 0x12B +#define STID_HELP_FILES_HLP 0x12C +#define STID_DIALOG_TEST 0x12D +#define STID_FILE_NOT_FOUND_s 0x12E