xpra icon
Bug tracker and wiki

This bug tracker and wiki are being discontinued
please use https://github.com/Xpra-org/xpra instead.


Ticket #56: _add-screen-size.patch

File _add-screen-size.patch, 9.5 KB (added by onlyjob, 9 years ago)

refreshed patch to apply over 0.6.1

  • wimpiggy/lowlevel/bindings.pyx

    Last-Update: 2012-09-18
    Bug-Xpra: http://xpra.org/trac/ticket/56
    Description:
     Instead of finding the nearest match, we should just add the modeline,
     assign it to the output then select it.
     This would allow us to match the client's screen size exactly.
    
    a b  
    12651265    cdef unsigned int RR_Rotate_0
    12661266
    12671267cdef extern from "X11/extensions/Xrandr.h":
     1268    ctypedef XID RRMode
     1269    ctypedef XID RROutput
     1270    ctypedef XID RRCrtc
     1271    ctypedef unsigned long XRRModeFlags
    12681272    Bool XRRQueryExtension(Display *, int *, int *)
    12691273    Status XRRQueryVersion(Display *, int * major, int * minor)
    12701274    ctypedef struct XRRScreenSize:
    12711275        int width, height
    12721276        int mwidth, mheight
     1277    ctypedef struct XRRModeInfo:
     1278        RRMode              id
     1279        unsigned int        width
     1280        unsigned int        height
     1281        unsigned long       dotClock
     1282        unsigned int        hSyncStart
     1283        unsigned int        hSyncEnd
     1284        unsigned int        hTotal
     1285        unsigned int        hSkew
     1286        unsigned int        vSyncStart
     1287        unsigned int        vSyncEnd
     1288        unsigned int        vTotal
     1289        char                *name
     1290        unsigned int        nameLength
     1291        XRRModeFlags        modeFlags
     1292    ctypedef struct XRRScreenResources:
     1293        Time        timestamp
     1294        Time        configTimestamp
     1295        int         ncrtc
     1296        RRCrtc      *crtcs
     1297        int         noutput
     1298        RROutput    *outputs
     1299        int         nmode
     1300        XRRModeInfo *modes
     1301
    12731302    XRRScreenSize *XRRSizes(Display *dpy, int screen, int *nsizes)
    12741303    void XRRSetScreenSize(Display *dpy, Window w, int width, int height, int mmWidth, int mmHeight)
    12751304
     
    12861315    SizeID XRRConfigCurrentConfiguration(XRRScreenConfiguration *config, Rotation *rotation)
    12871316
    12881317    void XRRFreeScreenConfigInfo(XRRScreenConfiguration *)
     1318    XRRScreenResources *XRRGetScreenResourcesCurrent(Display *dpy, Window window)
     1319    void XRRFreeScreenResources(XRRScreenResources *resources)
     1320
     1321    XRRModeInfo *XRRAllocModeInfo(char *name, int nameLength)
     1322    RRMode XRRCreateMode(Display *dpy, Window window, XRRModeInfo *modeInfo)
     1323    void XRRAddOutputMode(Display *dpy, RROutput output, RRMode mode)
     1324    void XRRFreeModeInfo(XRRModeInfo *modeInfo)
    12891325
    12901326def has_randr():
    12911327    try:
     
    13131349def get_screen_sizes():
    13141350    return _get_screen_sizes(gtk.gdk.display_get_default())
    13151351
     1352cdef _add_screen_size(display_source, pywindow, x, y):
     1353    cdef Display * display
     1354    cdef Window window
     1355    cdef XRRModeInfo * new_mode
     1356    cdef XRRScreenResources * rsc
     1357    cdef RRMode mode
     1358    cdef RROutput output
     1359   
     1360    #monitor settings as set in xorg.conf...
     1361    maxPixelClock = 230*1000*1000       #230MHz
     1362    minHSync = 10*1000                  #10KHz
     1363    maxHSync = 300*1000                 #300KHz
     1364    minVSync = 10                       #10Hz
     1365    maxVSync = 300                      #30Hz
     1366    idealVSync = 50.0;
     1367    timeHFront = 0.07       #0.074219; 0.075; Width of the black border on right edge of the screen
     1368    timeHSync = 0.1         #0.107422; 0.1125; Sync pulse duration
     1369    timeHBack = 0.15        #0.183594; 0.1875; Width of the black border on left edge of the screen
     1370    timeVBack = 0.06;       #0.031901; 0.055664; // Adjust this to move picture up/down
     1371    yFactor = 1             #no interlace (0.5) or doublescan (2)
     1372
     1373    if x%8!=0:
     1374        #round up to the nearest 8
     1375        x += 8-x%8
     1376    name = "%sx%s" % (x, y)
     1377    new_mode = XRRAllocModeInfo(name, len(name))
     1378    try:
     1379        display = get_xdisplay_for(display_source)
     1380        window = get_xwindow(pywindow)
     1381
     1382        xFront = int(x * timeHFront)
     1383        xSync = int(x * timeHSync)
     1384        xBack = int(x * timeHBack)
     1385        xTotal = x + xFront + xSync + xBack
     1386        yFront = 1
     1387        ySync = 3
     1388        yBack = int(y * timeVBack)
     1389        yTotal = y + yFront + ySync + yBack
     1390
     1391        modeMaxClock = maxPixelClock
     1392        if (maxHSync * xTotal)<maxPixelClock:
     1393            modeMaxClock = maxHSync * xTotal
     1394        tmp = maxVSync * xTotal * yTotal * yFactor
     1395        if tmp<modeMaxClock:
     1396            modeMaxClock = tmp
     1397        modeMinClock = minHSync * xTotal
     1398        # Monitor minVSync too low? => increase mode minimum pixel clock
     1399        tmp = minVSync * xTotal * yTotal * yFactor
     1400        if tmp > modeMinClock:
     1401            modeMinClock = tmp
     1402        # If minimum clock > maximum clock, the mode is impossible...
     1403        if modeMinClock > modeMaxClock:
     1404            print("No suitable clocks could be found")
     1405            return None
     1406
     1407        idealClock = idealVSync * xTotal * yTotal * yFactor
     1408        clock = idealClock;
     1409        if clock < modeMinClock:
     1410            clock = modeMinClock
     1411        elif clock > modeMaxClock:
     1412            clock = modeMaxClock
     1413       
     1414        print("Modeline %sx%s %s %s %s %s %s %s %s %s %s" % (x,y, clock/1000/1000,
     1415                        x, x+xFront, x+xFront+xSync, xTotal,
     1416                        y, y+yFront, y+yFront+ySync, yTotal))
     1417
     1418        new_mode.width = x
     1419        new_mode.height = y
     1420        new_mode.dotClock = long(clock)
     1421        new_mode.hSyncStart = int(x+xFront)
     1422        new_mode.hSyncEnd = int(x+xFront+xSync)
     1423        new_mode.hTotal = int(xTotal)
     1424        new_mode.hSkew = 0
     1425        new_mode.vSyncStart = int(y+yFront)
     1426        new_mode.vSyncEnd = int(y+yFront+ySync)
     1427        new_mode.vTotal = int(yTotal)
     1428        new_mode.modeFlags = 0
     1429        mode = XRRCreateMode(display, window, new_mode)
     1430        print("XRRCreateMode returned %s" % mode)
     1431        if mode<=0:
     1432            return None
     1433        #now add it to the output:
     1434        try:
     1435            rsc = XRRGetScreenResourcesCurrent(display, window)
     1436            print("screen_resources:")
     1437            print("crtcs=%s" % rsc.ncrtc)
     1438            print("outputs=%s" % rsc.noutput)
     1439            print("modes=%s" % rsc.nmode)
     1440            if rsc.noutput!=1:
     1441                print("unexpected number of outputs: %s" % rsc.noutput)
     1442                return None
     1443            output = rsc.outputs[0]
     1444            print("adding mode %s to output %s" % (mode,output))
     1445            XRRAddOutputMode(display, output, mode)
     1446            #and now use it:
     1447            #XRRSetScreenSize(display, window, x, y, int(x*0.4), int(y*0.4))
     1448        finally:
     1449            #pass
     1450            XRRFreeScreenResources(rsc)
     1451    finally:
     1452        #pass
     1453        XRRFreeModeInfo(new_mode)
     1454    sizes = _get_screen_sizes(display_source)
     1455    print("screen_sizes=%r" % (sizes,))
     1456    for sx,sy in sizes:
     1457        if sx==x and sy==y:
     1458            return x,y
     1459    print("new size not found!")
     1460    #get_screen_resources()
     1461    return None
     1462
     1463def add_screen_size(width, height):
     1464    display = gtk.gdk.display_get_default()
     1465    root_window = gtk.gdk.get_default_root_window()
     1466    return _add_screen_size(display, root_window, width, height)
     1467
     1468cdef get_screen_resources():
     1469    cdef Display * display
     1470    cdef Window window
     1471    cdef XRRScreenResources * rsc
     1472    cdef XRRModeInfo mode
     1473    display = get_xdisplay_for(gtk.gdk.display_get_default())
     1474    window = get_xwindow(gtk.gdk.get_default_root_window())
     1475    rsc = XRRGetScreenResourcesCurrent(display, window)
     1476    print("screen_resources:")
     1477    print("crtcs=%s" % rsc.ncrtc)
     1478    print("outputs=%s" % rsc.noutput)
     1479    print("modes=%s" % rsc.nmode)
     1480    i = 0
     1481    while i<rsc.nmode:
     1482        mode = rsc.modes[i]
     1483        i+=1
     1484        print("mode[%s]: %s,%s" % (i, mode.width, mode.height))
     1485
     1486
    13161487cdef _set_screen_size(display_source, pywindow, width, height):
    13171488    cdef Display * display
    13181489    cdef Window window
  • xpra/server.py

    a b  
    4141                               get_cursor_image,            #@UnresolvedImport
    4242                               get_children,                #@UnresolvedImport
    4343                               has_randr, get_screen_sizes, #@UnresolvedImport
     44                               add_screen_size,             #@UnresolvedImport
    4445                               set_screen_size,             #@UnresolvedImport
    4546                               get_screen_size,             #@UnresolvedImport
    4647                               init_x11_filter,             #@UnresolvedImport
     
    891892        root_w, root_h = gtk.gdk.get_default_root_window().get_size()
    892893        if desired_w==root_w and desired_h==root_h:
    893894            return    root_w,root_h    #unlikely: perfect match already!
    894         #try to find the best screen size to resize to:
    895         new_size = None
    896         for w,h in get_screen_sizes():
    897             if w<desired_w or h<desired_h:
    898                 continue            #size is too small for client
    899             if new_size:
    900                 ew,eh = new_size
    901                 if ew*eh<w*h:
    902                     continue        #we found a better (smaller) candidate already
    903             new_size = w,h
     895        #try to add the new size:
     896        new_size = add_screen_size(client_w, client_h)
     897        if not new_size:
     898            #try to find the best screen size to resize to:
     899            for w,h in get_screen_sizes():
     900                if w<desired_w or h<desired_h:
     901                    continue            #size is too small for client
     902                if new_size:
     903                    ew,eh = new_size
     904                    if ew*eh<w*h:
     905                        continue        #we found a better (smaller) candidate already
     906                new_size = w,h
    904907        log("best resolution for client(%sx%s) is: %s", desired_w, desired_h, new_size)
    905908        if not new_size:
    906909            return