• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/nix/xdg_util.h"
6 
7 #include <string>
8 
9 #include "base/base_paths.h"
10 #include "base/environment.h"
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/logging.h"
14 #include "base/path_service.h"
15 #include "base/strings/string_split.h"
16 #include "base/strings/string_util.h"
17 #include "base/third_party/xdg_user_dirs/xdg_user_dir_lookup.h"
18 
19 namespace {
20 
21 // The KDE session version environment variable introduced in KDE 4.
22 const char kKDESessionEnvVar[] = "KDE_SESSION_VERSION";
23 
24 }  // namespace
25 
26 namespace base {
27 namespace nix {
28 
29 const char kDotConfigDir[] = ".config";
30 const char kXdgConfigHomeEnvVar[] = "XDG_CONFIG_HOME";
31 const char kXdgCurrentDesktopEnvVar[] = "XDG_CURRENT_DESKTOP";
32 const char kXdgSessionTypeEnvVar[] = "XDG_SESSION_TYPE";
33 
GetXDGDirectory(Environment * env,const char * env_name,const char * fallback_dir)34 FilePath GetXDGDirectory(Environment* env, const char* env_name,
35                          const char* fallback_dir) {
36   FilePath path;
37   std::string env_value;
38   if (env->GetVar(env_name, &env_value) && !env_value.empty()) {
39     path = FilePath(env_value);
40   } else {
41     PathService::Get(DIR_HOME, &path);
42     path = path.Append(fallback_dir);
43   }
44   return path.StripTrailingSeparators();
45 }
46 
GetXDGUserDirectory(const char * dir_name,const char * fallback_dir)47 FilePath GetXDGUserDirectory(const char* dir_name, const char* fallback_dir) {
48   FilePath path;
49   char* xdg_dir = xdg_user_dir_lookup(dir_name);
50   if (xdg_dir) {
51     path = FilePath(xdg_dir);
52     free(xdg_dir);
53   } else {
54     PathService::Get(DIR_HOME, &path);
55     path = path.Append(fallback_dir);
56   }
57   return path.StripTrailingSeparators();
58 }
59 
GetDesktopEnvironment(Environment * env)60 DesktopEnvironment GetDesktopEnvironment(Environment* env) {
61   // kXdgCurrentDesktopEnvVar is the newest standard circa 2012.
62   std::string xdg_current_desktop;
63   if (env->GetVar(kXdgCurrentDesktopEnvVar, &xdg_current_desktop)) {
64     // It could have multiple values separated by colon in priority order.
65     for (const auto& value : SplitStringPiece(
66              xdg_current_desktop, ":", TRIM_WHITESPACE, SPLIT_WANT_NONEMPTY)) {
67       if (value == "Unity") {
68         // gnome-fallback sessions set kXdgCurrentDesktopEnvVar to Unity
69         // DESKTOP_SESSION can be gnome-fallback or gnome-fallback-compiz
70         std::string desktop_session;
71         if (env->GetVar("DESKTOP_SESSION", &desktop_session) &&
72             desktop_session.find("gnome-fallback") != std::string::npos) {
73           return DESKTOP_ENVIRONMENT_GNOME;
74         }
75         return DESKTOP_ENVIRONMENT_UNITY;
76       }
77       if (value == "Deepin")
78         return DESKTOP_ENVIRONMENT_DEEPIN;
79       if (value == "GNOME")
80         return DESKTOP_ENVIRONMENT_GNOME;
81       if (value == "X-Cinnamon")
82         return DESKTOP_ENVIRONMENT_CINNAMON;
83       if (value == "KDE") {
84         std::string kde_session;
85         if (env->GetVar(kKDESessionEnvVar, &kde_session)) {
86           if (kde_session == "5") {
87             return DESKTOP_ENVIRONMENT_KDE5;
88           }
89           if (kde_session == "6") {
90             return DESKTOP_ENVIRONMENT_KDE6;
91           }
92         }
93         return DESKTOP_ENVIRONMENT_KDE4;
94       }
95       if (value == "Pantheon")
96         return DESKTOP_ENVIRONMENT_PANTHEON;
97       if (value == "XFCE")
98         return DESKTOP_ENVIRONMENT_XFCE;
99       if (value == "UKUI")
100         return DESKTOP_ENVIRONMENT_UKUI;
101       if (value == "LXQt")
102         return DESKTOP_ENVIRONMENT_LXQT;
103     }
104   }
105 
106   // DESKTOP_SESSION was what everyone used in 2010.
107   std::string desktop_session;
108   if (env->GetVar("DESKTOP_SESSION", &desktop_session)) {
109     if (desktop_session == "deepin")
110       return DESKTOP_ENVIRONMENT_DEEPIN;
111     if (desktop_session == "gnome" || desktop_session == "mate")
112       return DESKTOP_ENVIRONMENT_GNOME;
113     if (desktop_session == "kde4" || desktop_session == "kde-plasma")
114       return DESKTOP_ENVIRONMENT_KDE4;
115     if (desktop_session == "kde") {
116       // This may mean KDE4 on newer systems, so we have to check.
117       if (env->HasVar(kKDESessionEnvVar))
118         return DESKTOP_ENVIRONMENT_KDE4;
119       return DESKTOP_ENVIRONMENT_KDE3;
120     }
121     if (desktop_session.find("xfce") != std::string::npos ||
122         desktop_session == "xubuntu") {
123       return DESKTOP_ENVIRONMENT_XFCE;
124     }
125     if (desktop_session == "ukui")
126       return DESKTOP_ENVIRONMENT_UKUI;
127   }
128 
129   // Fall back on some older environment variables.
130   // Useful particularly in the DESKTOP_SESSION=default case.
131   if (env->HasVar("GNOME_DESKTOP_SESSION_ID"))
132     return DESKTOP_ENVIRONMENT_GNOME;
133   if (env->HasVar("KDE_FULL_SESSION")) {
134     if (env->HasVar(kKDESessionEnvVar))
135       return DESKTOP_ENVIRONMENT_KDE4;
136     return DESKTOP_ENVIRONMENT_KDE3;
137   }
138 
139   return DESKTOP_ENVIRONMENT_OTHER;
140 }
141 
GetDesktopEnvironmentName(DesktopEnvironment env)142 const char* GetDesktopEnvironmentName(DesktopEnvironment env) {
143   switch (env) {
144     case DESKTOP_ENVIRONMENT_OTHER:
145       return nullptr;
146     case DESKTOP_ENVIRONMENT_CINNAMON:
147       return "CINNAMON";
148     case DESKTOP_ENVIRONMENT_DEEPIN:
149       return "DEEPIN";
150     case DESKTOP_ENVIRONMENT_GNOME:
151       return "GNOME";
152     case DESKTOP_ENVIRONMENT_KDE3:
153       return "KDE3";
154     case DESKTOP_ENVIRONMENT_KDE4:
155       return "KDE4";
156     case DESKTOP_ENVIRONMENT_KDE5:
157       return "KDE5";
158     case DESKTOP_ENVIRONMENT_KDE6:
159       return "KDE6";
160     case DESKTOP_ENVIRONMENT_PANTHEON:
161       return "PANTHEON";
162     case DESKTOP_ENVIRONMENT_UNITY:
163       return "UNITY";
164     case DESKTOP_ENVIRONMENT_XFCE:
165       return "XFCE";
166     case DESKTOP_ENVIRONMENT_UKUI:
167       return "UKUI";
168     case DESKTOP_ENVIRONMENT_LXQT:
169       return "LXQT";
170   }
171   return nullptr;
172 }
173 
GetDesktopEnvironmentName(Environment * env)174 const char* GetDesktopEnvironmentName(Environment* env) {
175   return GetDesktopEnvironmentName(GetDesktopEnvironment(env));
176 }
177 
GetSessionType(Environment & env)178 SessionType GetSessionType(Environment& env) {
179   std::string xdg_session_type;
180   if (!env.GetVar(kXdgSessionTypeEnvVar, &xdg_session_type))
181     return SessionType::kUnset;
182 
183   TrimWhitespaceASCII(ToLowerASCII(xdg_session_type), TrimPositions::TRIM_ALL,
184                       &xdg_session_type);
185 
186   if (xdg_session_type == "wayland")
187     return SessionType::kWayland;
188 
189   if (xdg_session_type == "x11")
190     return SessionType::kX11;
191 
192   if (xdg_session_type == "tty")
193     return SessionType::kTty;
194 
195   if (xdg_session_type == "mir")
196     return SessionType::kMir;
197 
198   if (xdg_session_type == "unspecified")
199     return SessionType::kUnspecified;
200 
201   LOG(ERROR) << "Unknown XDG_SESSION_TYPE: " << xdg_session_type;
202   return SessionType::kOther;
203 }
204 
205 }  // namespace nix
206 }  // namespace base
207