Skip to content

Commit

Permalink
#1232: support horizontal scrolling in client backends (pixmap and gl…
Browse files Browse the repository at this point in the history
…), and add tests for it

git-svn-id: https://xpra.org/svn/Xpra/trunk@12894 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Jun 23, 2016
1 parent 415cec5 commit 52400f3
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 104 deletions.
13 changes: 6 additions & 7 deletions src/tests/xpra/clients/test_backing_vscrollup.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,24 @@ class WindowAnim(object):

def __init__(self, window_class, client, wid, W=630, H=480):
self.wid = wid
self.W = W
self.H = H
self.window = window_class(client, None, 1, 10, 10, W, H, W, H, typedict({}), False, typedict({}), 0, None)
self.window = window_class(client, None, wid, 10, 10, W, H, W, H, typedict({}), False, typedict({}), 0, None)
self.window.show()
self.paint_rect(0, 0, W, H, chr(255)*4*W*H)
self.paint_rect(W//2-16, H//2-16, 32, 32, chr(0)*4*32*32)

def scrollup(self, ydelta=1):
print("scrollup(%s)" % ydelta)
scrolls = (0, ydelta, self.W, self.H-ydelta, -ydelta),
self.window.draw_region(0, 0, self.W, self.H, "scroll", scrolls, self.W*4, 0, typedict({"flush" : 0}), [])
W, H = self.window.get_size()
scrolls = (0, ydelta, W, H-ydelta, 0, -ydelta),
self.window.draw_region(0, 0, W, H, "scroll", scrolls, W*4, 0, typedict({"flush" : 0}), [])
dots = []
for _ in range(self.W*ydelta):
for _ in range(W*ydelta):
CB = 0xFF << ((self.wid % 4) * 8)
v = int(time.time()*10000)
c = struct.pack("@I", v & 0xFFFFFFFF & ~CB)
dots.append(c)
img_data = b"".join(dots)
self.paint_rect(0, self.H-ydelta, self.W, ydelta, img_data)
self.paint_rect(0, H-ydelta, W, ydelta, img_data)
return True

def scrolluponce(self, ydelta):
Expand Down
85 changes: 0 additions & 85 deletions src/tests/xpra/clients/test_gl_window.py

This file was deleted.

69 changes: 69 additions & 0 deletions src/tests/xpra/clients/test_scroll_circle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#!/usr/bin/env python
# This file is part of Xpra.
# Copyright (C) 2012, 2013 Antoine Martin <[email protected]>
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

import math
from xpra.log import Logger
log = Logger()

import glib

from xpra.util import typedict
from tests.xpra.clients.fake_gtk_client import FakeGTKClient, gtk_main
from xpra.codecs.loader import load_codecs

load_codecs(encoders=False, decoders=True, csc=False)


class WindowAnim(object):

def __init__(self, window_class, client, wid=1, W=630, H=480):
self.wid = wid
self.window = window_class(client, None, wid, 10, 10, W, H, W, H, typedict({}), False, typedict({}), 0, None)
self.window.show()
self.paint_rect(0, 0, W, H, chr(255)*4*W*H)
self.paint_rect(W//2-16, H//2-16, 64, 64, chr(0)*4*64*64)
self.counter = 0
self.delta_x = 0
self.delta_y = 0

def paint_rect(self, x=200, y=200, w=32, h=32, img_data=None, options={}):
assert img_data
self.window.draw_region(x, y, w, h, "rgb32", img_data, w*4, 0, typedict(options), [])

def movearound(self, ydelta=1):
self.counter += 1
RADIUS = 128
target_x = int(math.sin(self.counter/10.0) * RADIUS)
target_y = int(math.cos(self.counter/10.0) * RADIUS)
dx = target_x - self.delta_x
dy = target_y - self.delta_y
W, H = self.window.get_size()
scrolls = (RADIUS, RADIUS, W-RADIUS*2, H-RADIUS*2, dx, dy),
self.window.draw_region(0, 0, W, H, "scroll", scrolls, W*4, 0, typedict({"flush" : 0}), [])
self.delta_x = target_x
self.delta_y = target_y
return True


def main():
import sys
client = FakeGTKClient()
try:
from xpra.client.gl.gtk2.gl_client_window import GLClientWindow
window_class = GLClientWindow
except:
from xpra.client.gtk2.border_client_window import BorderClientWindow
window_class = BorderClientWindow
anim = WindowAnim(window_class, client)
glib.timeout_add(100, anim.movearound)
try:
gtk_main()
except KeyboardInterrupt:
pass


if __name__ == "__main__":
main()
99 changes: 99 additions & 0 deletions src/tests/xpra/clients/test_window_scroll_and_paint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env python
# This file is part of Xpra.
# Copyright (C) 2012, 2013 Antoine Martin <[email protected]>
# Xpra is released under the terms of the GNU GPL v2, or, at your option, any
# later version. See the file COPYING for details.

import binascii
import math
from xpra.log import Logger
log = Logger()

import glib

from xpra.util import typedict
from tests.xpra.clients.fake_gtk_client import FakeGTKClient, gtk_main
from xpra.codecs.loader import load_codecs

load_codecs(encoders=False, decoders=True, csc=False)


class WindowAnim(object):

def __init__(self, window_class, client, wid, W=630, H=480):
self.wid = wid
self.window = window_class(client, None, wid, 10, 10, W, H, W, H, typedict({}), False, typedict({}), 0, None)
self.window.show()
self.paint_rect(0, 0, W, H, chr(255)*4*W*H)

def paint_crect(self, x=200, y=200, w=32, h=32, color=0x80808080):
import struct
c = struct.pack("@I", color & 0xFFFFFFFF)
img_data = c*w*h
self.window.draw_region(x, y, w, h, "rgb32", img_data, w*4, 0, typedict({}), [])

def paint_rect(self, x=200, y=200, w=32, h=32, img_data=None, options={}):
assert img_data
self.window.draw_region(x, y, w, h, "rgb32", img_data, w*4, 0, typedict(options), [])

def paint_png(self, x=256, y=256):
W, H = self.window.get_size()
img_data = binascii.unhexlify("89504e470d0a1a0a0000000d494844520000010000000100010300000066bc3a2500000003504c54"
"45b5d0d0630416ea0000001f494441546881edc1010d000000c2a0f74f6d0e37a000000000000000"
"00be0d210000019a60e1d50000000049454e44ae426082")
self.window.draw_region((W-x)//2, (H-x)//2, x, y, "png", img_data, W*4, 0, typedict(), [])

def paint_and_vscroll(self, ydelta=10, color=0xA0A0A0A):
print("paint_and_scroll(%i, %#x)" % (ydelta, color))
W, H = self.window.get_size()
if ydelta>0:
#scroll down, repaint the top:
scrolls = (0, 0, W, H-ydelta, 0, ydelta),
self.window.draw_region(0, 0, W, H, "scroll", scrolls, W*4, 0, typedict({"flush" : 1}), [])
self.paint_crect(0, 0, W, ydelta, color << ydelta)
else:
#scroll up, repaint the bottom:
scrolls = (0, -ydelta, W, H+ydelta, 0, ydelta),
self.window.draw_region(0, 0, W, H, "scroll", scrolls, W*4, 0, typedict({"flush" : 1}), [])
self.paint_crect(0, H-ydelta, W, -ydelta, color >> -ydelta)

def split_vscroll(self, i=1):
W, H = self.window.get_size()
scrolls = [
(0, i, W, H//2-i, 0, -i),
(0, H//2, W, H//2-i, 0, i),
]
self.window.draw_region(0, 0, W, H, "scroll", scrolls, W*4, 0, typedict({}), [])


def main():
W = 640
H = 480
try:
from xpra.client.gl.gtk2.gl_client_window import GLClientWindow
window_class = GLClientWindow
except:
from xpra.client.gtk2.border_client_window import BorderClientWindow
window_class = BorderClientWindow
client = FakeGTKClient()
window = WindowAnim(window_class, client, 1)
window.paint_png()
for i in range(4):
glib.timeout_add(500, window.paint_crect, W//4*i + W//8, 100, 32, 32, 0x30*i)
for i in range(50):
glib.timeout_add(1000+i*20, window.paint_crect, int(W//3+math.sin(i/10.0)*128), int(H//2-32+math.cos(i/10.0)*64))
glib.timeout_add(1000+i*20, window.paint_and_vscroll, -1)
glib.timeout_add(2000+i*20, window.paint_crect, int(W//3*2-math.sin(i/10.0)*128), int(H//2-16-math.cos(i/10.0)*64), 32, 32)
glib.timeout_add(2000+i*20, window.paint_and_vscroll, +1)
for i in range(200):
glib.timeout_add(4000+i*20, window.split_vscroll, max(1, i//50))
glib.timeout_add(4000+i*20, window.paint_crect, 0, H//2-1, W, 2)

try:
gtk_main()
except KeyboardInterrupt:
pass


if __name__ == "__main__":
main()
17 changes: 10 additions & 7 deletions src/xpra/client/gl/gl_window_backing_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,14 +480,17 @@ def do_scroll_paints(self, scrolls, flush=0):
0, 0, bw, bh,
GL_COLOR_BUFFER_BIT, GL_NEAREST)

for x,y,w,h,ydelta in scrolls:
assert ydelta!=0 and abs(ydelta)<bh, "invalid ydelta value: %i" % ydelta
assert w>0 and h>0
assert x+w<=bw and y+h<=bh, "scroll rectangle overflows the buffer: %s vs %s" % ((x, y, w, h), self.size)
assert y+ydelta>=0 and y+h+ydelta<=bh, "invalid vertical scroll value %i for rectangle %s overflows the buffer size %s" % (ydelta, (x, y, w, h), self.size)
#invert Y coordinates (bh-?)
for x,y,w,h,xdelta,ydelta in scrolls:
assert abs(xdelta)<bw, "invalid xdelta value: %i" % xdelta
assert abs(ydelta)<bh, "invalid ydelta value: %i" % ydelta
assert ydelta!=0 or xdelta!=0, "scroll has no delta!"
assert w>0 and h>0, "scroll area is empty: %ix%i" % (w, h)
assert x+w<=bw and y+h<=bh, "scroll rectangle %s too big for the buffer: %s" % ((x, y, w, h), self.size)
assert x+xdelta>=0 and x+w+xdelta<=bw, "horizontal scroll by %i: rectangle %s overflows the backing buffer size %s" % (xdelta, (x, y, w, h), self.size)
assert y+ydelta>=0 and y+h+ydelta<=bh, "vertical scroll by %i: rectangle %s overflows the backing buffer size %s" % (ydelta, (x, y, w, h), self.size)
#opengl buffer is upside down, so we must invert Y coordinates: bh-(..)
glBlitFramebuffer(x, bh-y, x+w, bh-(y+h),
x, bh-(y+ydelta), x+w, bh-(y+h+ydelta),
x+xdelta, bh-(y+ydelta), x+w+xdelta, bh-(y+h+ydelta),
GL_COLOR_BUFFER_BIT, GL_NEAREST)

#now swap references to tmp and offscreen so tmp becomes the new offscreen:
Expand Down
9 changes: 4 additions & 5 deletions src/xpra/client/gtk2/pixmap_backing.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,15 +128,14 @@ def do_paint_scroll(self, x, y, w, h, scrolls, options, callbacks):
cr.set_source_pixmap(old_backing, 0, 0)
cr.paint()
#then the regions that moved:
for sx,sy,sw,sh,ydelta in scrolls:
for sx,sy,sw,sh,xdelta,ydelta in scrolls:
#assert y+ydelta>=0 and y+h+ydelta<=h
cr.save()
cr = self._backing.cairo_create()
#cr = self._backing.cairo_create()
cr.translate(0, ydelta)
cr.translate(xdelta, ydelta)
cr.set_source_pixmap(old_backing, 0, 0)
cr.rectangle(sx, sy-ydelta, sw, sh)
cr.rectangle(sx, sy, sw, sh)
cr.paint()
cr.restore()
fire_paint_callbacks(callbacks, True)

def bgr_to_rgb(self, img_data, width, height, rowstride, rgb_format, target_format):
Expand Down

0 comments on commit 52400f3

Please sign in to comment.