home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 mARCH / PCWK3A99.iso / Linux / DDD331 / DDD-3_1_.000 / DDD-3_1_ / ddd-3.1.1 / ddd / xconfig.C < prev    next >
C/C++ Source or Header  |  1998-11-16  |  9KB  |  404 lines

  1. // $Id: xconfig.C,v 1.23 1998/11/16 14:33:21 zeller Exp $ -*- C++ -*-
  2. // Setup X defaults and determine common problem causes.
  3.  
  4. // Copyright (C) 1995 Technische Universitaet Braunschweig, Germany.
  5. // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
  6. // 
  7. // This file is part of DDD.
  8. // 
  9. // DDD is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. // 
  14. // DDD is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. // See the GNU General Public License for more details.
  18. // 
  19. // You should have received a copy of the GNU General Public
  20. // License along with DDD -- see the file COPYING.
  21. // If not, write to the Free Software Foundation, Inc.,
  22. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. // 
  24. // DDD is the data display debugger.
  25. // For details, see the DDD World-Wide-Web page, 
  26. // `http://www.cs.tu-bs.de/softech/ddd/',
  27. // or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
  28.  
  29. char xconfig_rcsid[] = 
  30.     "$Id: xconfig.C,v 1.23 1998/11/16 14:33:21 zeller Exp $";
  31.  
  32. #ifdef __GNUG__
  33. #pragma implementation
  34. #endif
  35.  
  36. #include "xconfig.h"
  37. #include "strclass.h"
  38. #include "bool.h"
  39. #include "cook.h"
  40. #include "filetype.h"
  41.  
  42. #include <unistd.h>
  43. #include <stdio.h>
  44. #include <stdlib.h>
  45. #include <string.h>
  46. #include <errno.h>
  47.  
  48. #include <limits.h>
  49. #ifndef PATH_MAX
  50. #define PATH_MAX 4096
  51. #endif
  52.  
  53. #include <Xm/VirtKeys.h>
  54. #include <Xm/SelectioB.h>
  55.  
  56. #if !HAVE_POPEN_DECL
  57. extern "C" FILE *popen(const char *command, const char *mode);
  58. #endif
  59. #if !HAVE_PCLOSE_DECL
  60. extern "C" int pclose(FILE *stream);
  61. #endif
  62.  
  63.  
  64. //-----------------------------------------------------------------------------
  65. // Determine X project root
  66. //-----------------------------------------------------------------------------
  67.  
  68. inline string sh_quote(string s)
  69. {
  70.     s.gsub('\'', "'\\''");
  71.     return string('\'') + s + '\'';
  72. }
  73.  
  74. inline string dirname(string file)
  75. {
  76.     if (file.contains('/'))
  77.     return file.before('/', -1);
  78.     else
  79.     return ".";
  80. }
  81.  
  82. static bool is_file(string file)
  83. {
  84.     FILE *fp = fopen(file, "r");
  85.     if (fp == 0)
  86.     return false;
  87.  
  88.     fclose(fp);
  89.     return true;
  90. }
  91.  
  92. // Fetch the X library directory, using xmkmf(1)
  93. static String xlibdir(Display *display, bool verbose = false)
  94. {
  95.     static bool tried = false;
  96.     static String dir = 0;
  97.  
  98.     if (tried)
  99.     return dir;
  100.     tried = true;
  101.  
  102.     if (!is_cmd_file(cmd_file("xmkmf")))
  103.     return dir;        // No `xmkmf' in PATH
  104.     if (!is_cmd_file(cmd_file("make")))
  105.     return dir;        // No `make' in PATH
  106.  
  107.     static const char shell_command[] =
  108.     ""
  109. #include "xlibdir.C"
  110.     "";
  111.  
  112.     String me, my_class;
  113.     XtGetApplicationNameAndClass(display, &me, &my_class);
  114.  
  115.     if (verbose)
  116.     {
  117.     cout << "Checking for X11 library directory... ";
  118.     cout.flush();
  119.     }
  120.  
  121.     FILE *fp = popen("/bin/sh -c " + sh_quote(shell_command), "r");
  122.     if (fp == 0)
  123.     {
  124.     if (verbose)
  125.     {
  126.         cout << strerror(errno) << "\n";
  127.         cout.flush();
  128.     }
  129.     return dir;
  130.     }
  131.  
  132.     char buffer[PATH_MAX];
  133.     buffer[0] = '\0';
  134.     fgets(buffer, sizeof(buffer), fp);
  135.     pclose(fp);
  136.  
  137.     int len = strlen(buffer);
  138.     if (len > 0 && buffer[len - 1] == '\n')
  139.     buffer[len - 1] = '\0';
  140.  
  141.     if (buffer[0] == '/')    // Sanity check
  142.     dir = (String)XtNewString(buffer);
  143.  
  144.     if (verbose)
  145.     {
  146.     if (dir)
  147.         cout << dir << "\n";
  148.     else
  149.         cout << "(not found)\n";
  150.     cout.flush();
  151.     }
  152.  
  153.     return dir;
  154. }
  155.  
  156. static int check_xkeysymdb(Display *display, bool verbose)
  157. {
  158.     if (verbose)
  159.     {
  160.     (void) xlibdir(display, verbose);
  161.     }
  162.  
  163.     if (verbose)
  164.     {
  165.     cout << "Checking for XKeysymDB... ";
  166.     cout.flush();
  167.     }
  168.  
  169.     String me, my_class;
  170.     XtGetApplicationNameAndClass(display, &me, &my_class);
  171.  
  172.     String xkeysymdb = 0;
  173.  
  174.     if (xkeysymdb == 0)
  175.     xkeysymdb = getenv("XKEYSYMDB");
  176.     if (xkeysymdb == 0)
  177.     xkeysymdb = XtResolvePathname(display, "", "XKeysymDB", "",
  178.                       NULL, NULL, 0, NULL);
  179.  
  180.     if (xkeysymdb)
  181.     {
  182.     if (verbose)
  183.     {
  184.         cout << xkeysymdb << "\n";
  185.         cout.flush();
  186.     }
  187.  
  188.     // Fix it now
  189.     static string env;
  190.     env = "XKEYSYMDB=" + string(xkeysymdb);
  191.     putenv(env);
  192.     return 0;            // Okay
  193.     }
  194.     
  195.  
  196.     if (xlibdir(display) != 0)
  197.     {
  198.     string path = string(xlibdir(display)) + "/XKeysymDB";
  199.     if (is_file(path))
  200.     {
  201.         if (verbose)
  202.         {
  203.         cout << path << "\n"
  204.              << "Note: this is not the default path compiled into " 
  205.              << me << ".\n"
  206.              << "    To avoid having " << me 
  207.              << " determine this setting each time it is started,\n"
  208.              << "    please set the XKEYSYMDB "
  209.              << "environment variable to\n"
  210.              << "    " << quote(path) << ".\n";
  211.         cout.flush();
  212.         }
  213.  
  214.         // Fix it
  215.         static string env;
  216.         env = "XKEYSYMDB=" + path;
  217.         putenv(env);
  218.         return 0;
  219.     }
  220.     }
  221.  
  222.     cout << "(none)\n";
  223.     cout.flush();
  224.  
  225.     if (verbose)
  226.     {
  227.     cout << "Warning: The `XKeysymDB' file is not in the "
  228.          << "default X file search path.\n"
  229.          << "    If " << me << " was not compiled on this machine, " 
  230.          << me << "\n" 
  231.          << "    may not run properly "
  232.          << "(lots of warnings for unknown keysym names).\n"
  233.          << "    Please get the `XKeysymDB' file from\n"
  234.          << "    `ftp://ftp.ips.cs.tu-bs.de/pub/local/softech/ddd/bin/'\n";
  235.  
  236.     if (xlibdir(display) != 0)
  237.         cout << "    and install it into `" << xlibdir(display, verbose) 
  238.          << "'\n";
  239.     else
  240.         cout << "    and install it into your X project root "
  241.          << "(typically `/usr/lib/X11')\n";
  242.  
  243.     cout << "    or have the XKEYSYMDB environment variable "
  244.          << "point at it.\n";
  245.  
  246.     cout.flush();
  247.     }
  248.  
  249.     return 1;
  250. }
  251.  
  252. #if XlibSpecificationRelease == 5 && !__hpux__
  253. static String resolve_dirname(Display *display, String type, String name)
  254. {
  255.     String ret = XtResolvePathname(display, type, name, "", 
  256.                    NULL, NULL, 0, NULL);
  257.  
  258.     if (ret != 0)
  259.     {
  260.     static string dir;
  261.     dir = dirname(ret);
  262.     ret = (char *)dir.chars();
  263.     }
  264.  
  265.     return ret;
  266. }
  267. #endif
  268.  
  269. static int check_xnlspath(Display *display, bool verbose)
  270. {
  271. #if XlibSpecificationRelease == 5
  272.     if (verbose)
  273.     {
  274.     (void) xlibdir(display, verbose);
  275.     }
  276.  
  277.     if (verbose)
  278.     {
  279.     cout << "Checking for nls directory... ";
  280.     cout.flush();
  281.     }
  282.  
  283.     String me, my_class;
  284.     XtGetApplicationNameAndClass(display, &me, &my_class);
  285.  
  286.     String xnlspath = 0;
  287.  
  288.     if (xnlspath == 0)
  289.     xnlspath = getenv("XNLSPATH");
  290.  
  291. #if __hpux__
  292.     // On HP-UX, checking for nonexistent files (notably,
  293.     // `nls/nls.dir') causes `illegal instruction' crashes.  The
  294.     // following call, however, works on HP-UX.  Reported by
  295.     // Tobias Mangold <mangold@hft.e-technik.tu-muenchen.de>.
  296.     if (xnlspath == 0)
  297.     xnlspath = XtResolvePathname(display, "nls", "", "", 
  298.                      NULL, NULL, 0, NULL);
  299. #else
  300.     // Check for `nls/C' or `nls/nls.dir'
  301.     if (xnlspath == 0)
  302.     xnlspath = resolve_dirname(display, "nls", "C");
  303.     if (xnlspath == 0)
  304.     xnlspath = resolve_dirname(display, "nls", "nls.dir");
  305. #endif
  306.  
  307.     if (xnlspath)
  308.     {
  309.     if (verbose)
  310.     {
  311.         cout << xnlspath << "\n";
  312.         cout.flush();
  313.     }
  314.  
  315.     // Fix it now
  316.     static string env;
  317.     env = string("XNLSPATH=") + xnlspath;
  318.     putenv(env);
  319.     return 0;        // Okay
  320.     }
  321.  
  322.     if (xlibdir(display, verbose) != 0)
  323.     {
  324.     string path = string(xlibdir(display, verbose)) + "/nls";
  325.     if (!is_directory(path))
  326.     {
  327.         if (verbose)
  328.         {
  329.         cout << path << "\n"
  330.              << "Note: this is not the default path compiled into " 
  331.              << me << ".\n"
  332.              << "    To avoid having " << me 
  333.              << " determine this setting each time it is started,\n"
  334.              << "    please set the XNLSPATH "
  335.              << "environment variable to\n"
  336.              << "    " << quote(path) << ".\n\n";
  337.         cout.flush();
  338.         }
  339.  
  340.         // Fix it now
  341.         static string env;
  342.         env = "XNLSPATH=" + path;
  343.         putenv(env);
  344.         return 0;
  345.     }
  346.     }
  347.  
  348.     if (verbose)
  349.     {
  350.     cout << "Warning: cannot locate the X11 `nls' directory!\n"
  351.          << "    If " << me << " was not compiled on this machine, " 
  352.          << me << "\n" 
  353.          << "    may not run properly (`cut and paste' fails).\n"
  354.          << "    Please get the `nls' directory from\n"
  355.          << "    `ftp://ftp.ips.cs.tu-bs.de/pub/local/softech/ddd/bin/'\n";
  356.  
  357.     if (xlibdir(display) != 0)
  358.         cout << "    and install it into `" << xlibdir(display) << "'\n";
  359.     else
  360.         cout << "    and install it into your X project root "
  361.          << "(typically `/usr/lib/X11')\n";
  362.     cout << "    or have the XNLSPATH environment variable "
  363.          << "point at it.\n\n";
  364.     cout.flush();
  365.     }
  366.  
  367.     return 1;
  368. #else // XlibSpecificationRelease != 5
  369.  
  370.     (void) display;        // Use it
  371.     (void) verbose;
  372.  
  373.     // In X11R4, there was no nls directory; X11R6 has a `locale' dir instead.
  374.     return 0;
  375.  
  376. #endif // XlibSpecificationRelease != 5
  377. }
  378.  
  379.  
  380. // Set up the X11 library directory
  381. int check_x_configuration(Widget toplevel, bool verbose)
  382. {
  383.     Display *display = XtDisplay(toplevel);
  384.  
  385.     int ret = 0;
  386.  
  387.     // This is required for all Motif programs.
  388.     ret = check_xkeysymdb(display, verbose) || ret;
  389.  
  390.     // This is required for executables linked against X11R5 or later.
  391.     ret = check_xnlspath(display, verbose) || ret;
  392.  
  393.     if (verbose)
  394.     {
  395.     if (ret == 0)
  396.     {
  397.         cout << "No configuration problems found.\n";
  398.         cout.flush();
  399.     }
  400.     }
  401.  
  402.     return ret;
  403. }
  404.