w32reg.c 4.38 KB
Newer Older
Geoff Voelker's avatar
Geoff Voelker committed
1
/* Emulate the X Resource Manager through the registry.
2

Paul Eggert's avatar
Paul Eggert committed
3
Copyright (C) 1990, 1993-1994, 2001-2019 Free Software Foundation, Inc.
4 5

Author: Kevin Gallo
Geoff Voelker's avatar
Geoff Voelker committed
6

7 8
This file is part of GNU Emacs.

9
GNU Emacs is free software: you can redistribute it and/or modify
Geoff Voelker's avatar
Geoff Voelker committed
10
it under the terms of the GNU General Public License as published by
11 12
the Free Software Foundation, either version 3 of the License, or (at
your option) any later version.
Geoff Voelker's avatar
Geoff Voelker committed
13

14
GNU Emacs is distributed in the hope that it will be useful,
Geoff Voelker's avatar
Geoff Voelker committed
15 16 17 18 19
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
20
along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
Geoff Voelker's avatar
Geoff Voelker committed
21 22 23 24

#include <config.h>
#include "lisp.h"
#include "blockinput.h"
25
#include "w32term.h"
Geoff Voelker's avatar
Geoff Voelker committed
26 27 28

#include <stdio.h>

29
#define REG_ROOT "SOFTWARE\\GNU\\Emacs"
Geoff Voelker's avatar
Geoff Voelker committed
30

31 32 33 34 35 36 37 38 39 40
/* Default system colors from the Display Control Panel settings.  */
#define SYSTEM_DEFAULT_RESOURCES                          \
  "emacs.foreground:SystemWindowText\0"			  \
  "emacs.background:SystemWindow\0"                       \
  "emacs.tooltip.attributeForeground:SystemInfoText\0"    \
  "emacs.tooltip.attributeBackground:SystemInfoWindow\0"  \
  "emacs.tool-bar.attributeForeground:SystemButtonText\0" \
  "emacs.tool-bar.attributeBackground:SystemButtonFace\0" \
  "emacs.menu.attributeForeground:SystemMenuText\0"       \
  "emacs.menu.attributeBackground:SystemMenu\0"           \
41
  "emacs.scroll-bar.attributeForeground:SystemScrollbar\0"
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57

/* Other possibilities for default faces:

  region: Could use SystemHilight, but interferes with our ability to
  see most syntax highlighting through the region face.

  modeline: Could use System(In)ActiveTitle, gradient versions (not
  supported on 95 and NT), but modeline is more like a status bar
  really (which don't appear to be configurable in Windows).

  highlight: Could use SystemHotTrackingColor, but it is not supported
  on Windows 95 or NT, and other apps only seem to use it for menus
  anyway.

*/

58
static char *
59
w32_get_rdb_resource (const char *rdb, const char *resource)
60
{
61
  char *value = (char *)rdb;
62 63 64 65 66 67 68 69 70 71 72 73 74 75
  int len = strlen (resource);

  while (*value)
    {
      /* Comparison is case-insensitive because registry searches are too.  */
      if ((strnicmp (value, resource, len) == 0) && (value[len] == ':'))
        return xstrdup (&value[len + 1]);

      value = strchr (value, '\0') + 1;
    }

  return NULL;
}

76 77
static const char *
w32_get_string_resource_1 (const char *name, const char *class, DWORD dwexptype)
Geoff Voelker's avatar
Geoff Voelker committed
78 79 80 81 82 83
{
  LPBYTE lpvalue = NULL;
  HKEY hrootkey = NULL;
  DWORD dwType;
  DWORD cbData;
  BOOL ok = FALSE;
84
  HKEY hive = HKEY_CURRENT_USER;
85

86 87
 trykey:

88
  block_input ();
89

90 91 92 93
  /* Check both the current user and the local machine to see if we have
     any resources */

  if (RegOpenKeyEx (hive, REG_ROOT, 0, KEY_READ, &hrootkey) == ERROR_SUCCESS)
Geoff Voelker's avatar
Geoff Voelker committed
94
    {
95
      const char *keyname;
96

Geoff Voelker's avatar
Geoff Voelker committed
97 98 99 100
      if (RegQueryValueEx (hrootkey, name, NULL, &dwType, NULL, &cbData) == ERROR_SUCCESS
	  && dwType == dwexptype)
	{
	  keyname = name;
101
	}
Geoff Voelker's avatar
Geoff Voelker committed
102 103 104 105 106 107 108 109 110
      else if (RegQueryValueEx (hrootkey, class, NULL, &dwType, NULL, &cbData) == ERROR_SUCCESS
	       && dwType == dwexptype)
	{
	  keyname = class;
	}
      else
	{
	  keyname = NULL;
	}
111

Geoff Voelker's avatar
Geoff Voelker committed
112
      ok = (keyname
Dmitry Antipov's avatar
Dmitry Antipov committed
113
	    && (lpvalue = xmalloc (cbData)) != NULL
Geoff Voelker's avatar
Geoff Voelker committed
114
	    && RegQueryValueEx (hrootkey, keyname, NULL, NULL, lpvalue, &cbData) == ERROR_SUCCESS);
115

Geoff Voelker's avatar
Geoff Voelker committed
116 117
      RegCloseKey (hrootkey);
    }
118

119
  unblock_input ();
120 121

  if (!ok)
Geoff Voelker's avatar
Geoff Voelker committed
122
    {
123 124 125 126 127 128 129 130 131 132
      if (lpvalue)
	{
	  xfree (lpvalue);
	  lpvalue = NULL;
	}
      if (hive == HKEY_CURRENT_USER)
	{
	  hive = HKEY_LOCAL_MACHINE;
	  goto trykey;
	}
133 134 135

      /* Check if there are Windows specific defaults defined.  */
      return w32_get_rdb_resource (SYSTEM_DEFAULT_RESOURCES, name);
136
    }
137
  return (const char *)lpvalue;
Geoff Voelker's avatar
Geoff Voelker committed
138 139 140 141 142
}

/* Retrieve the string resource specified by NAME with CLASS from
   database RDB. */

143 144
const char *
w32_get_string_resource (void *v_rdb, const char *name, const char *class)
Geoff Voelker's avatar
Geoff Voelker committed
145
{
146
  const char *rdb = *(char **) v_rdb;
147

148 149 150 151
  if (rdb)
    {
      char *resource;

152
      if ((resource = w32_get_rdb_resource (rdb, name)))
153
        return resource;
154
      if ((resource = w32_get_rdb_resource (rdb, class)))
155 156 157
        return resource;
    }

158 159 160 161
  if (inhibit_x_resources)
    /* --quick was passed, so this is a no-op.  */
    return NULL;

162
  return w32_get_string_resource_1 (name, class, REG_SZ);
Geoff Voelker's avatar
Geoff Voelker committed
163
}