Search code examples
pythonpython-3.xxlibxrandr

What is the CARD variable type in XRANDR?


Edit2: Just to make it clear, integers are what I originally entered into the program. My original code, before I started testing anything, was this:

import struct
from Xlib import X, display, Xutil
from Xlib.ext import randr

d = display.Display(':0')
screen = 0
info = d.screen(screen)
window = info.root
randr.set_screen_size(window, 2000, 2000)

and it gave me the same struct.error: required argument is not an integer. I have also done randr.set_screen_size(window,int(2000),int(2000)), just to make sure that I was entering integers, and that has also returned the same struct.error.

Edit1: From what I understand it seems that CARD is an unsigned integer type, and CARD16 is an unsigned 16 bit short. According to Roland Smith's answer, is seems that the way this is handled in the python Xlib library is through struct. As such I checked that I was passing integers to the argument, and I was. I also tried making them into unsigned 16 bit integers ahead of time, but that did not work. This is my current code:

import struct
from Xlib import X, display, Xutil
from Xlib.ext import randr

d = display.Display(':0')
screen = 0
info = d.screen(screen)
window = info.root
short16bit = struct.pack("H", int(2000))
randr.set_screen_size(window, short16bit, short16bit)

and this is the full error:

Traceback (most recent call last):
  File "/home/deishuukaikirpi/XRANDRTesting.py", line 59, in <module>
    randr.set_screen_size(window, short16bit, short16bit)
  File "/home/deishuukaikirpi/.local/lib/python3.9/site-packages/Xlib/ext/randr.py", line 387, in set_screen_size
    return SetScreenSize(
  File "/home/deishuukaikirpi/.local/lib/python3.9/site-packages/Xlib/protocol/rq.py", line 1347, in __init__
    self._binary = self._request.to_binary(*args, **keys)
  File "/home/deishuukaikirpi/.local/lib/python3.9/site-packages/Xlib/protocol/rq.py", line 1069, in to_binary
    static_part = struct.pack(self.static_codes, *pack_items)
struct.error: required argument is not an integer

I still get the same struct.error: required argument is not an integer error. Interestingly enough, if I put a large enough integer into width or height I instead get the error struct.error: ushort format requires 0 <= number <= (0x7fff * 2 + 1), which does seem to imply that this is an unsigned short.

Original: I am working on a program that lets me manipulate displays through Python-Xlib. I got everything working and figured everything out until I hit randr.set_screen_size(). It has three necessary arguments - self, which takes a window variable, as well as length and width which both take CARD16 variables respectively. The documentation that I found of XRANDR which I have been using, found here, outlines CARD32, CARD16, and CARD8 as variable types but does not explain what they are nor how to produce them.

I thought that they were originally just special integer variables, and as such entered integers. I got the error "struct.error: required argument is not an integer." I then tried putting in a string as well as binary via the bin function and both of them returned the same error as when I entered an integer.


Solution

  • Okay, I found the problem. set_screen_size actually takes 5 parameters: self, which takes a window object, width and height which each take CARD16 objects, and finally width_in_millimeters and height_in_millimeters which take CARD32 objects. I didn't think that width_in_millimeters or height_in_millimeters mattered because they are set to None automatically in the Xlib code, but apparently it does matter. This still hasn't gotten the program working, because now, instead of returning an error, it just isn't doing what its supposed to do, but I'm going to start a new question for that.

    So to answer the title question: CARD is short for Cardinal number. Cardinal numbers are non-negative integers. CARD8, CARD16, and CARD32, in XRANDR, are an unsigned character, an unsigned short, and an unsigned long, respectively. Python does not natively support these, but they can be recreated using the struct library.