mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
CtrlLib: ChX11 removed dump_xsettings dependency
This commit is contained in:
parent
7a56ea2931
commit
5f4a15be79
1 changed files with 158 additions and 87 deletions
|
|
@ -3,104 +3,175 @@
|
|||
#ifdef GUI_X11
|
||||
|
||||
namespace Upp {
|
||||
|
||||
#define LLOG(x)
|
||||
|
||||
VectorMap<String, Value> GetXSettings()
|
||||
{
|
||||
VectorMap<String, Value> map;
|
||||
|
||||
Window owner = XGetSelectionOwner(Xdisplay, XAtom("_XSETTINGS_S0"));
|
||||
|
||||
if(owner == None) {
|
||||
LLOG("No XSettings manager found for screen " << screen);
|
||||
return map;
|
||||
}
|
||||
|
||||
Atom settings_atom = XAtom("_XSETTINGS_SETTINGS");
|
||||
String data = GetProperty(owner, settings_atom, settings_atom);
|
||||
|
||||
if(data.IsEmpty()) {
|
||||
LLOG("Failed to read XSettings property or property is empty.");
|
||||
return map;
|
||||
}
|
||||
|
||||
const char *ptr = data.Begin();
|
||||
const char *lim = data.End();
|
||||
|
||||
if(data.GetCount() < 12)
|
||||
return map;
|
||||
|
||||
byte be = ptr[0];
|
||||
|
||||
auto Peek32 = [&](const char *p) {
|
||||
return be ? Peek32be(p) : Peek32le(p);
|
||||
};
|
||||
|
||||
auto Peek16 = [&](const char *p) {
|
||||
return be ? Peek16be(p) : Peek16le(p);
|
||||
};
|
||||
|
||||
int n_settings = Peek32(ptr + 8);
|
||||
ptr += 12;
|
||||
|
||||
for(int i = 0; i < n_settings && ptr < lim; i++) {
|
||||
if(lim - ptr < 4)
|
||||
break;
|
||||
|
||||
byte type = *ptr++; // 0 = Integer, 1 = String, 2 = Color
|
||||
ptr++; // unused
|
||||
|
||||
int name_len = Peek16(ptr);
|
||||
ptr += 2;
|
||||
if(lim - ptr < name_len)
|
||||
break;
|
||||
String name(ptr, name_len);
|
||||
ptr += (name_len + 3) & ~3;
|
||||
|
||||
ptr += 4; // Last-change serial
|
||||
|
||||
if(type == 0) { // Integer
|
||||
if(lim - ptr < 4)
|
||||
break;
|
||||
map.GetAdd(name) = (int)Peek32(ptr);
|
||||
ptr += 4;
|
||||
}
|
||||
else
|
||||
if(type == 1) { // String
|
||||
if(lim - ptr < 4)
|
||||
break;
|
||||
int str_len = Peek32(ptr);
|
||||
ptr += 4;
|
||||
if(lim - ptr < str_len)
|
||||
break;
|
||||
map.GetAdd(name) = String(ptr, str_len);
|
||||
ptr += (str_len + 3) & ~3; // Align to 4 bytes
|
||||
}
|
||||
else
|
||||
if(type == 2) { // Color - ignored
|
||||
if(lim - ptr < 8)
|
||||
break;
|
||||
ptr += 8;
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
void ChHostSkin()
|
||||
{
|
||||
String s = Sys("dump_xsettings");
|
||||
StringStream ss(s);
|
||||
String font_name, theme;
|
||||
int scaling = 1;
|
||||
int xdpi = 98347;
|
||||
while(!ss.IsEof()) {
|
||||
String l = ss.GetLine();
|
||||
int q = l.Find(' ');
|
||||
if(q >= 0) {
|
||||
String id = l.Mid(0, q);
|
||||
String value = l.Mid(q + 1);
|
||||
if(id == "Gdk/WindowScalingFactor")
|
||||
scaling = max(Atoi(value), 1);
|
||||
if(id == "Gtk/FontName")
|
||||
font_name = value;
|
||||
if(id == "Xft/DPI")
|
||||
xdpi = Nvl(StrInt(value), 98347);
|
||||
if(id == "Net/ThemeName")
|
||||
theme = value;
|
||||
}
|
||||
}
|
||||
|
||||
int fontface = Font::ARIAL;
|
||||
int fontheight = 13;
|
||||
bool bold = false;
|
||||
bool italic = false;
|
||||
|
||||
const char *q = strrchr(font_name, ' ');
|
||||
if(q) {
|
||||
int h = atoi(q);
|
||||
if(h)
|
||||
fontheight = h;
|
||||
String face(font_name, q);
|
||||
fontface = Font::FindFaceNameIndex(face);
|
||||
|
||||
if(fontface == 0) {
|
||||
for(;;) {
|
||||
const char *q = strrchr(face, ' ');
|
||||
if(!q) break;
|
||||
const char *s = q + 1;
|
||||
if(stricmp(s, "Bold") == 0 || stricmp(s, "Heavy") == 0)
|
||||
bold = true;
|
||||
else
|
||||
if(stricmp(s, "Italic") == 0 || stricmp(s, "Oblique") == 0)
|
||||
italic = true;
|
||||
else
|
||||
if(stricmp(s, "Regular") == 0 || stricmp(s, "Light") || stricmp(s, "Medium"))
|
||||
;
|
||||
else
|
||||
continue;
|
||||
face = String(~face, q);
|
||||
}
|
||||
VectorMap<String, Value> map = GetXSettings();
|
||||
try {
|
||||
String font_name = map.Get("Gtk/FontName", "");
|
||||
String theme = map.Get("Net/ThemeName", "");
|
||||
//int scaling = map.Get("Gdk/WindowScalingFactor", 1);
|
||||
int xdpi = map.Get("Xft/DPI", 98347);
|
||||
|
||||
int fontface = Font::ARIAL;
|
||||
int fontheight = 13;
|
||||
bool bold = false;
|
||||
bool italic = false;
|
||||
|
||||
const char *q = strrchr(font_name, ' ');
|
||||
if(q) {
|
||||
int h = atoi(q);
|
||||
if(h)
|
||||
fontheight = h;
|
||||
String face(font_name, q);
|
||||
fontface = Font::FindFaceNameIndex(face);
|
||||
|
||||
if(fontface == 0) {
|
||||
if(ToUpper(face[0]) == 'M')
|
||||
fontface = Font::COURIER;
|
||||
else
|
||||
if(ToUpper(face[0]) == 'S' && ToUpper(face[1]) == 'e')
|
||||
fontface = Font::ROMAN;
|
||||
else
|
||||
fontface = Font::ARIAL;
|
||||
for(;;) {
|
||||
const char *q = strrchr(face, ' ');
|
||||
if(!q) break;
|
||||
const char *s = q + 1;
|
||||
if(stricmp(s, "Bold") == 0 || stricmp(s, "Heavy") == 0)
|
||||
bold = true;
|
||||
else
|
||||
if(stricmp(s, "Italic") == 0 || stricmp(s, "Oblique") == 0)
|
||||
italic = true;
|
||||
else
|
||||
if(stricmp(s, "Regular") == 0 || stricmp(s, "Light") || stricmp(s, "Medium"))
|
||||
;
|
||||
else
|
||||
continue;
|
||||
face = String(~face, q);
|
||||
}
|
||||
fontface = Font::FindFaceNameIndex(face);
|
||||
if(fontface == 0) {
|
||||
if(ToUpper(face[0]) == 'M')
|
||||
fontface = Font::COURIER;
|
||||
else
|
||||
if(ToUpper(face[0]) == 'S' && ToUpper(face[1]) == 'e')
|
||||
fontface = Font::ROMAN;
|
||||
else
|
||||
fontface = Font::ARIAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Font gui_font = Font(fontface, fround(fontheight * xdpi / (72*1024.0))).Bold(bold).Italic(italic);
|
||||
Font::SetDefaultFont(gui_font);
|
||||
|
||||
Font gui_font = Font(fontface, fround(fontheight * xdpi / (72*1024.0))).Bold(bold).Italic(italic);
|
||||
Font::SetDefaultFont(gui_font);
|
||||
|
||||
SColorFace_Write(Color(242, 241, 240));
|
||||
SColorMenu_Write(Color(242, 241, 240));
|
||||
SColorHighlight_Write(Color(50, 50, 250));
|
||||
|
||||
auto ThemeHasWord = [&](const char *text) {
|
||||
int q = ToLower(theme).Find(text);
|
||||
if(q >= 0) {
|
||||
if(q > 0) {
|
||||
int pc = theme[q - 1];
|
||||
if(!(IsUpper(theme[q]) && IsLower(pc) || !IsLetter(pc)))
|
||||
SColorFace_Write(Color(242, 241, 240));
|
||||
SColorMenu_Write(Color(242, 241, 240));
|
||||
SColorHighlight_Write(Color(50, 50, 250));
|
||||
|
||||
auto ThemeHasWord = [&](const char *text) {
|
||||
int q = ToLower(theme).Find(text);
|
||||
if(q >= 0) {
|
||||
if(q > 0) {
|
||||
int pc = theme[q - 1];
|
||||
if(!(IsUpper(theme[q]) && IsLower(pc) || !IsLetter(pc)))
|
||||
return false;
|
||||
}
|
||||
int l = strlen(text);
|
||||
int nc = theme[q + l];
|
||||
if(!(IsLower(text[l - 1]) && IsUpper(nc) || !IsLetter(nc)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
int l = strlen(text);
|
||||
int nc = theme[q + l];
|
||||
if(!(IsLower(text[l - 1]) && IsUpper(nc) || !IsLetter(nc)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if(ThemeHasWord("dark") || ThemeHasWord("inverse") || ThemeHasWord("black"))
|
||||
ChDarkSkin();
|
||||
else
|
||||
ChStdSkin();
|
||||
return false;
|
||||
};
|
||||
|
||||
if(ThemeHasWord("dark") || ThemeHasWord("inverse") || ThemeHasWord("black"))
|
||||
ChDarkSkin();
|
||||
else
|
||||
ChStdSkin();
|
||||
}
|
||||
catch(ValueTypeError) {}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue