xrandrl 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #!/usr/bin/env python3
  2. # PYTHON_ARGCOMPLETE_OK
  3. """
  4. sudo apt-get install libx11-dev libxrandr-dev
  5. https://cgit.freedesktop.org/xorg/app/xrandr/tree/xrandr.c
  6. """
  7. import ctypes
  8. import sys
  9. Time = ctypes.c_ulong
  10. """
  11. #ifndef _XTYPEDEF_XID
  12. # define _XTYPEDEF_XID
  13. # ifndef _XSERVER64
  14. typedef unsigned long XID;
  15. # else
  16. typedef CARD32 XID;
  17. # endif
  18. #endif
  19. """
  20. XID = ctypes.c_ulong
  21. """
  22. typedef XID RROutput;
  23. """
  24. RROutput = XID
  25. """
  26. typedef XID RRCrtc;
  27. """
  28. RRCrtc = XID
  29. """ /usr/include/X11/extensions/Xrandr.h
  30. typedef XID RRMode;
  31. """
  32. RRMode = XID
  33. """ /usr/include/X11/extensions/randr.h
  34. #define RR_Connected 0
  35. """
  36. RR_Connected = 0
  37. """ /usr/include/X11/extensions/randr.h
  38. typedef unsigned short Connection;
  39. """
  40. Connection = ctypes.c_ushort
  41. """ /usr/include/X11/extensions/randr.h
  42. typedef unsigned short SubpixelOrder;
  43. """
  44. SubpixelOrder = ctypes.c_ushort
  45. """ /usr/include/X11/extensions/Xrandr.h
  46. typedef struct _XRRScreenResources {
  47. Time timestamp;
  48. Time configTimestamp;
  49. int ncrtc;
  50. RRCrtc *crtcs;
  51. int noutput;
  52. RROutput *outputs;
  53. int nmode;
  54. XRRModeInfo *modes;
  55. } XRRScreenResources;
  56. """
  57. class XRRScreenResources(ctypes.Structure):
  58. _fields_ = [
  59. ('timestamp', Time),
  60. ('configTimestamp', Time),
  61. ('ncrtc', ctypes.c_int),
  62. ('crtcs', ctypes.POINTER(RRCrtc)),
  63. ('noutput', ctypes.c_int),
  64. ('outputs', ctypes.POINTER(RROutput)),
  65. ('nmode', ctypes.c_int),
  66. ('modes', ctypes.c_void_p), # ctypes.POINTER(XRRModeInfo)
  67. ]
  68. """
  69. typedef struct _XRROutputInfo {
  70. Time timestamp;
  71. RRCrtc crtc;
  72. char *name;
  73. int nameLen;
  74. unsigned long mm_width;
  75. unsigned long mm_height;
  76. Connection connection;
  77. SubpixelOrder subpixel_order;
  78. int ncrtc;
  79. RRCrtc *crtcs;
  80. int nclone;
  81. RROutput *clones;
  82. int nmode;
  83. int npreferred;
  84. RRMode *modes;
  85. } XRROutputInfo;
  86. """
  87. class XRROutputInfo(ctypes.Structure):
  88. _fields_ = [
  89. ('timestamp', Time),
  90. ('crtc', RRCrtc),
  91. ('name', ctypes.c_char_p),
  92. ('nameLen', ctypes.c_int),
  93. ('mm_width', ctypes.c_ulong),
  94. ('mm_height', ctypes.c_ulong),
  95. ('connection', Connection),
  96. ('subpixel_order', SubpixelOrder),
  97. ('ncrtc', ctypes.c_int),
  98. ('crtcs', ctypes.POINTER(RRCrtc)),
  99. ('nclone', ctypes.c_int),
  100. ('clones', ctypes.POINTER(RROutput)),
  101. ('nmode', ctypes.c_int),
  102. ('npreferred', ctypes.c_int),
  103. ('modes', ctypes.POINTER(RRMode)),
  104. ]
  105. X11 = ctypes.cdll.LoadLibrary("libX11.so")
  106. Xrandr = ctypes.cdll.LoadLibrary("libXrandr.so")
  107. Xrandr.XRRGetScreenResourcesCurrent.restype = ctypes.POINTER(
  108. XRRScreenResources)
  109. """
  110. XRROutputInfo *
  111. XRRGetOutputInfo (Display *dpy, XRRScreenResources *resources, RROutput output);
  112. """
  113. Xrandr.XRRGetOutputInfo.restype = ctypes.POINTER(XRROutputInfo)
  114. def get_xrandr_output_infos(xdisplay):
  115. screen_resrcs = Xrandr.XRRGetScreenResourcesCurrent(
  116. xdisplay,
  117. X11.XDefaultRootWindow(xdisplay),
  118. )
  119. assert isinstance(screen_resrcs.contents, XRRScreenResources)
  120. return [Xrandr.XRRGetOutputInfo(xdisplay, screen_resrcs, screen_resrcs.contents.outputs[o])
  121. for o in range(screen_resrcs.contents.noutput)]
  122. def process(connected):
  123. xdisplay = X11.XOpenDisplay(None)
  124. for output_info in get_xrandr_output_infos(xdisplay):
  125. if not connected or output_info.contents.connection == RR_Connected:
  126. output_name = output_info.contents.name \
  127. .decode(sys.getfilesystemencoding())
  128. print(output_name)
  129. X11.XCloseDisplay(xdisplay)
  130. def _init_argparser():
  131. import argparse
  132. argparser = argparse.ArgumentParser(description=None)
  133. argparser.add_argument(
  134. '--connected',
  135. action='store_true',
  136. help='connected only',
  137. )
  138. return argparser
  139. def main(argv):
  140. argparser = _init_argparser()
  141. try:
  142. import argcomplete
  143. except ImportError:
  144. pass
  145. args = argparser.parse_args(argv)
  146. process(**vars(args))
  147. return 0
  148. if __name__ == "__main__":
  149. sys.exit(main(sys.argv[1:]))