您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. var udev = require("../../udev");
  2. var xrandr = require("./xrandr");
  3. var table = require("../../js/table");
  4. var spawn = require("child_process").spawn;
  5. exports.start = start;
  6. exports.stop = stop;
  7. exports.event = event;
  8. exports.list = list;
  9. var conf;
  10. var logger;
  11. var modules;
  12. function findMode(display, mode) {
  13. if (mode === "max")
  14. return display.modes[0];
  15. for (var i in display.modes) {
  16. if (display.modes[i].resStr == mode)
  17. return display.modes[i];
  18. }
  19. return null;
  20. }
  21. function findRate(mode, rate) {
  22. if (rate === "max")
  23. return mode.rates[0];
  24. for (var i in mode.rates) {
  25. if (mode.rates[i] == rate)
  26. return mode.rates[i];
  27. }
  28. return null;
  29. }
  30. function randr(args) {
  31. var cmd = "xrandr";
  32. var child = spawn(cmd, args);
  33. child.stderr.on("data", d => logger.warn("xrandr:", d.toString()));
  34. }
  35. function turnOff(display) {
  36. var args = [
  37. "--output", display.id,
  38. "--off"
  39. ];
  40. randr(args);
  41. }
  42. function applyRule(primary, rule, display) {
  43. var args = [ "--output", display.id ];
  44. if (rule.rate != null && rule.mode == null)
  45. return logger.warn("Display "+rule.name+": 'rate' specified without 'mode'");
  46. var mode;
  47. if (rule.mode != null) {
  48. mode = findMode(display, rule.mode);
  49. if (mode == null)
  50. return logger.warn(
  51. "Display "+rule.name+": Invalid mode: "+rule.res);
  52. args.push("--mode");
  53. args.push(mode.resStr);
  54. }
  55. var rate;
  56. if (rule.rate != null) {
  57. rate = findRate(mode, rule.rate);
  58. if (rate == null)
  59. return logger.warn(
  60. "Display "+rule.name+": Invalid rate: "+rule.rate);
  61. args.push("--rate");
  62. args.push(rate);
  63. }
  64. if (rule.where) {
  65. var w = rule.where;
  66. for (var i in w) {
  67. if (
  68. i !== "left-of" && i !== "right-of" &&
  69. i !== "above" && i !== "below") {
  70. return logger.warn(
  71. "Display "+rule.name+": Invalid 'where' value: "+i);
  72. }
  73. if (w[i] === "primary" && display === primary)
  74. continue;
  75. var id;
  76. if (w[i] === "primary") {
  77. id = primary.id;
  78. } else {
  79. id = w[i];
  80. }
  81. args.push("--"+i);
  82. args.push(id);
  83. }
  84. }
  85. randr(args);
  86. }
  87. function onchange() {
  88. if (conf == null) {
  89. setTimeout(() => modules.wallpaper.event("reload"), 0);
  90. logger.info("No displays configured.");
  91. return;
  92. }
  93. xrandr.list(data => {
  94. // Trun off all disconnected displays
  95. data.displays.filter(d => !d.connected).forEach(turnOff);
  96. var displays = data.displays.filter(d => d.connected);
  97. var primary = displays.filter(d => d.primary)[0];
  98. conf.forEach(entry => {
  99. displays.forEach(disp => {
  100. if (entry.name !== "*" && entry.name !== disp.id)
  101. return;
  102. applyRule(primary, entry, disp);
  103. });
  104. });
  105. setTimeout(() => modules.wallpaper.event("reload"), 400);
  106. });
  107. }
  108. function start(conf_, logger_, modules_) {
  109. conf = conf_ || conf;
  110. logger = logger_ || logger;
  111. modules = modules_ || modules;
  112. onchange();
  113. udev.monitor("drm", onchange);
  114. }
  115. function stop(cb) {
  116. udev.unmonitor("drm", onchange);
  117. cb();
  118. }
  119. function event(name, ...params) {
  120. switch (name) {
  121. default:
  122. logger.warn("Unknown event:", name);
  123. }
  124. }
  125. function list(cb) {
  126. xrandr.list(devs => {
  127. devs.displays.forEach(dev => {
  128. console.error(
  129. "\tname: "+dev.id+
  130. (dev.connected ? ", connected" : "")+
  131. (dev.primary ? ", primary" : ""));
  132. var data = [];
  133. for (var i in dev.modes) {
  134. var mode = dev.modes[i];
  135. data[i] = [];
  136. var d = data[i];
  137. d.push("mode: "+mode.resStr+",");
  138. d.push("rate:");
  139. mode.rates.forEach(r => d.push(r));
  140. }
  141. table(console.error.bind(console), data, "\t\t");
  142. });
  143. cb();
  144. });
  145. }