xpra icon
Bug tracker and wiki

Ticket #56: add-screen-size.patch

File add-screen-size.patch, 9.5 KB (added by Antoine Martin, 7 years ago)

this patch would add a new mode to Xdummy so we can use it... but does not work

  • xpra/server.py

     
    4646                               get_cursor_image,            #@UnresolvedImport
    4747                               get_children,                #@UnresolvedImport
    4848                               has_randr, get_screen_sizes, #@UnresolvedImport
     49                               add_screen_size,             #@UnresolvedImport
    4950                               set_screen_size,             #@UnresolvedImport
    5051                               get_screen_size)             #@UnresolvedImport
    5152from wimpiggy.prop import prop_set
     
    10331034        (root_w, root_h) = gtk.gdk.get_default_root_window().get_size()
    10341035        if client_w==root_w and client_h==root_h:
    10351036            return    root_w,root_h    #unlikely: perfect match already!
    1036         #try to find the best screen size to resize to:
    1037         new_size = None
    1038         for w,h in get_screen_sizes():
    1039             if w<client_w or h<client_h:
    1040                 continue            #size is too small for client
    1041             if new_size:
    1042                 ew,eh = new_size
    1043                 if ew*eh<w*h:
    1044                     continue        #we found a better (smaller) candidate already
    1045             new_size = w,h
     1037        #try to add the new size:
     1038        new_size = add_screen_size(client_w, client_h)
     1039        if not new_size:
     1040            #try to find the best screen size to resize to:
     1041            for w,h in get_screen_sizes():
     1042                if w<client_w or h<client_h:
     1043                    continue            #size is too small for client
     1044                if new_size:
     1045                    ew,eh = new_size
     1046                    if ew*eh<w*h:
     1047                        continue        #we found a better (smaller) candidate already
     1048                new_size = w,h
    10461049        log.debug("best resolution for client(%sx%s) is: %s", client_w, client_h, new_size)
    10471050        if new_size:
    10481051            w, h = new_size
  • wimpiggy/lowlevel/bindings.pyx

     
    11131113    cdef unsigned int RR_Rotate_0
    11141114
    11151115cdef extern from "X11/extensions/Xrandr.h":
     1116    ctypedef XID RRMode
     1117    ctypedef XID RROutput
     1118    ctypedef XID RRCrtc
     1119    ctypedef unsigned long XRRModeFlags
    11161120    Bool XRRQueryExtension(Display *, int *, int *)
    11171121    Status XRRQueryVersion(Display *, int * major, int * minor)
    11181122    ctypedef struct XRRScreenSize:
    11191123        int width, height
    11201124        int mwidth, mheight
     1125    ctypedef struct XRRModeInfo:
     1126        RRMode              id
     1127        unsigned int        width
     1128        unsigned int        height
     1129        unsigned long       dotClock
     1130        unsigned int        hSyncStart
     1131        unsigned int        hSyncEnd
     1132        unsigned int        hTotal
     1133        unsigned int        hSkew
     1134        unsigned int        vSyncStart
     1135        unsigned int        vSyncEnd
     1136        unsigned int        vTotal
     1137        char                *name
     1138        unsigned int        nameLength
     1139        XRRModeFlags        modeFlags
     1140    ctypedef struct XRRScreenResources:
     1141        Time        timestamp
     1142        Time        configTimestamp
     1143        int         ncrtc
     1144        RRCrtc      *crtcs
     1145        int         noutput
     1146        RROutput    *outputs
     1147        int         nmode
     1148        XRRModeInfo *modes
     1149
    11211150    XRRScreenSize *XRRSizes(Display *dpy, int screen, int *nsizes)
    11221151    void XRRSetScreenSize(Display *dpy, Window w, int width, int height, int mmWidth, int mmHeight)
    11231152
     
    11341163    SizeID XRRConfigCurrentConfiguration(XRRScreenConfiguration *config, Rotation *rotation)
    11351164
    11361165    void XRRFreeScreenConfigInfo(XRRScreenConfiguration *)
     1166    XRRScreenResources *XRRGetScreenResourcesCurrent(Display *dpy, Window window)
     1167    void XRRFreeScreenResources(XRRScreenResources *resources)
    11371168
     1169    XRRModeInfo *XRRAllocModeInfo(char *name, int nameLength)
     1170    RRMode XRRCreateMode(Display *dpy, Window window, XRRModeInfo *modeInfo)
     1171    void XRRAddOutputMode(Display *dpy, RROutput output, RRMode mode)
     1172    void XRRFreeModeInfo(XRRModeInfo *modeInfo)
     1173
    11381174def has_randr():
    11391175    try:
    11401176        _ensure_extension_support(gtk.gdk.get_default_root_window(), 1, 2, "Randr",
     
    11611197def get_screen_sizes():
    11621198    return _get_screen_sizes(gtk.gdk.display_get_default())
    11631199
     1200cdef _add_screen_size(display_source, pywindow, x, y):
     1201    cdef Display * display
     1202    cdef Window window
     1203    cdef XRRModeInfo * new_mode
     1204    cdef XRRScreenResources * rsc
     1205    cdef RRMode mode
     1206    cdef RROutput output
     1207   
     1208    #monitor settings as set in xorg.conf...
     1209    maxPixelClock = 230*1000*1000       #230MHz
     1210    minHSync = 10*1000                  #10KHz
     1211    maxHSync = 300*1000                 #300KHz
     1212    minVSync = 10                       #10Hz
     1213    maxVSync = 300                      #30Hz
     1214    idealVSync = 50.0;
     1215    timeHFront = 0.07       #0.074219; 0.075; Width of the black border on right edge of the screen
     1216    timeHSync = 0.1         #0.107422; 0.1125; Sync pulse duration
     1217    timeHBack = 0.15        #0.183594; 0.1875; Width of the black border on left edge of the screen
     1218    timeVBack = 0.06;       #0.031901; 0.055664; // Adjust this to move picture up/down
     1219    yFactor = 1             #no interlace (0.5) or doublescan (2)
     1220
     1221    if x%8!=0:
     1222        #round up to the nearest 8
     1223        x += 8-x%8
     1224    name = "%sx%s" % (x, y)
     1225    new_mode = XRRAllocModeInfo(name, len(name))
     1226    try:
     1227        display = get_xdisplay_for(display_source)
     1228        window = get_xwindow(pywindow)
     1229
     1230        xFront = int(x * timeHFront)
     1231        xSync = int(x * timeHSync)
     1232        xBack = int(x * timeHBack)
     1233        xTotal = x + xFront + xSync + xBack
     1234        yFront = 1
     1235        ySync = 3
     1236        yBack = int(y * timeVBack)
     1237        yTotal = y + yFront + ySync + yBack
     1238
     1239        modeMaxClock = maxPixelClock
     1240        if (maxHSync * xTotal)<maxPixelClock:
     1241            modeMaxClock = maxHSync * xTotal
     1242        tmp = maxVSync * xTotal * yTotal * yFactor
     1243        if tmp<modeMaxClock:
     1244            modeMaxClock = tmp
     1245        modeMinClock = minHSync * xTotal
     1246        # Monitor minVSync too low? => increase mode minimum pixel clock
     1247        tmp = minVSync * xTotal * yTotal * yFactor
     1248        if tmp > modeMinClock:
     1249            modeMinClock = tmp
     1250        # If minimum clock > maximum clock, the mode is impossible...
     1251        if modeMinClock > modeMaxClock:
     1252            print("No suitable clocks could be found")
     1253            return None
     1254
     1255        idealClock = idealVSync * xTotal * yTotal * yFactor
     1256        clock = idealClock;
     1257        if clock < modeMinClock:
     1258            clock = modeMinClock
     1259        elif clock > modeMaxClock:
     1260            clock = modeMaxClock
     1261       
     1262        print("Modeline %sx%s %s %s %s %s %s %s %s %s %s" % (x,y, clock/1000/1000,
     1263                        x, x+xFront, x+xFront+xSync, xTotal,
     1264                        y, y+yFront, y+yFront+ySync, yTotal))
     1265
     1266        new_mode.width = x
     1267        new_mode.height = y
     1268        new_mode.dotClock = long(clock)
     1269        new_mode.hSyncStart = int(x+xFront)
     1270        new_mode.hSyncEnd = int(x+xFront+xSync)
     1271        new_mode.hTotal = int(xTotal)
     1272        new_mode.hSkew = 0
     1273        new_mode.vSyncStart = int(y+yFront)
     1274        new_mode.vSyncEnd = int(y+yFront+ySync)
     1275        new_mode.vTotal = int(yTotal)
     1276        new_mode.modeFlags = 0
     1277        mode = XRRCreateMode(display, window, new_mode)
     1278        print("XRRCreateMode returned %s" % mode)
     1279        if mode<=0:
     1280            return None
     1281        #now add it to the output:
     1282        try:
     1283            rsc = XRRGetScreenResourcesCurrent(display, window)
     1284            print("screen_resources:")
     1285            print("crtcs=%s" % rsc.ncrtc)
     1286            print("outputs=%s" % rsc.noutput)
     1287            print("modes=%s" % rsc.nmode)
     1288            if rsc.noutput!=1:
     1289                print("unexpected number of outputs: %s" % rsc.noutput)
     1290                return None
     1291            output = rsc.outputs[0]
     1292            print("adding mode %s to output %s" % (mode,output))
     1293            XRRAddOutputMode(display, output, mode)
     1294            #and now use it:
     1295            #XRRSetScreenSize(display, window, x, y, int(x*0.4), int(y*0.4))
     1296        finally:
     1297            #pass
     1298            XRRFreeScreenResources(rsc)
     1299    finally:
     1300        #pass
     1301        XRRFreeModeInfo(new_mode)
     1302    sizes = _get_screen_sizes(display_source)
     1303    print("screen_sizes=%r" % (sizes,))
     1304    for sx,sy in sizes:
     1305        if sx==x and sy==y:
     1306            return x,y
     1307    print("new size not found!")
     1308    #get_screen_resources()
     1309    return None
     1310
     1311def add_screen_size(width, height):
     1312    display = gtk.gdk.display_get_default()
     1313    root_window = gtk.gdk.get_default_root_window()
     1314    return _add_screen_size(display, root_window, width, height)
     1315
     1316cdef get_screen_resources():
     1317    cdef Display * display
     1318    cdef Window window
     1319    cdef XRRScreenResources * rsc
     1320    cdef XRRModeInfo mode
     1321    display = get_xdisplay_for(gtk.gdk.display_get_default())
     1322    window = get_xwindow(gtk.gdk.get_default_root_window())
     1323    rsc = XRRGetScreenResourcesCurrent(display, window)
     1324    print("screen_resources:")
     1325    print("crtcs=%s" % rsc.ncrtc)
     1326    print("outputs=%s" % rsc.noutput)
     1327    print("modes=%s" % rsc.nmode)
     1328    i = 0
     1329    while i<rsc.nmode:
     1330        mode = rsc.modes[i]
     1331        i+=1
     1332        print("mode[%s]: %s,%s" % (i, mode.width, mode.height))
     1333
     1334
    11641335cdef _set_screen_size(display_source, pywindow, width, height):
    11651336    cdef Display * display
    11661337    cdef Window window