Exemplo n.º 1
0
    def __init__(self):
        assert len(sys.argv) == 4
        self.size = map(int, sys.argv[1].split("x"))
        orig = map(int, sys.argv[2].split("x"))
        self.orig = orig[1], orig[0]
        self.path = sys.argv[3]

        self.scalel = True
        self.scalep = False

        ml = self.orig[0] / float(self.size[0])
        self.sizel = self.size[0], int(self.orig[1] / ml)
        self.yl = (self.size[1] - self.sizel[1]) / 2

        mp = self.orig[0] / float(self.size[1])
        self.sizep = int(self.orig[1] / mp), self.size[1]
        self.xp = int((self.size[0] - self.sizep[0]) / 2)

        self.screen = pygame.display.set_mode(self.size)

        self.cap = CapClient(self)
        self.cap.start()

        self.touch = TouchClient(self)
        self.touch.start()

        self.rot = RotationClient()
        self.rot.start()

        self.mouse_down = False
Exemplo n.º 2
0
    def __init__(self):
        assert len(sys.argv) == 4
        self.size = list(map(int, sys.argv[1].split("x")))
        orig = list(map(int, sys.argv[2].split("x")))
        self.orig = orig[0], orig[1]
        self.path = sys.argv[3]

        self.cap = CapClient(self)
        self.cap.start()
        self.touch = TouchClient(self)
        self.touch.max_x = orig[0]
        self.touch.max_y = orig[1]
        self.touch.start()

        self.mouse_down = False
        self.mouse_pos = (0, 0)

        self.scale = self.orig[0] / float(self.size[0])
        self.ratio = self.orig[1] / float(self.orig[0])
        print('Scale, ratio:', self.scale, self.ratio)

        self.sizep = self.size[0], int(self.orig[1] / self.scale)
        self.sizel = int(self.orig[1] / self.scale), self.size[0]
        print('Raw image size l/p:', self.sizel, self.sizep)

        self.rotation = 0
        self.calc_scale()

        pygame.init()
        pygame.font.init()
        self.screen = pygame.display.set_mode(self.size)
Exemplo n.º 3
0
    def __init__(self):
        assert len(sys.argv) == 4
        self.rotation = 0  # or 90 for landscape
        self.winrotation = self.rotation
        p_size = list(map(int, sys.argv[1].split("x")))
        p_orig = list(map(int, sys.argv[2].split("x")))

        self.size = p_size[0], p_size[1]
        self.orig = p_orig[0], p_orig[1]
        # My Add
        if self.winrotation in [90, 270]:
            self.size = p_size[1], p_size[0]
            self.orig = p_orig[1], p_orig[0]

        self.path = sys.argv[3]

        self.cap = CapClient(self)
        self.cap.start()
        self.touch = TouchClient(self)
        self.touch.start()

        self.mouse_down = False
        self.mouse_pos = (0, 0)

        self.scale = self.orig[0] / float(self.size[0])
        self.ratio = self.orig[1] / float(self.orig[0])
        print('Scale, ratio:', self.scale, self.ratio)

        self.sizep = self.size[0], int(self.orig[1] / self.scale)
        self.sizel = int(self.orig[1] / self.scale), self.size[0]
        print('Raw image size l/p:', self.sizel, self.sizep)

        #self.rotation = 0 # Mii: 0, 90, 270 == NG
        self.calc_scale()
        self.state_str = '-Start-'

        pygame.init()
        pygame.font.init()
        # pygame.key.set_repeat(delay, interval)
        pygame.key.set_repeat(30, 30)

        self.screen = pygame.display.set_mode(self.size)
Exemplo n.º 4
0
    def __init__(self):
        assert len(sys.argv) == 4
        self.size = map(int, sys.argv[1].split("x"))
        orig = map(int, sys.argv[2].split("x"))
        self.orig = orig[1], orig[0]
        self.path = sys.argv[3]

        self.scalel = True
        self.scalep = False

        self.cap = CapClient(self)
        self.cap.start()

        self.touch = TouchClient(self)
        self.touch.start()

        self.rot = RotationClient()
        self.rot.start()

        self.adb = AdbClient()
        self.adb.start()

        self.mouse_down = False
        self.mouse_time = 0
        self.mouse_inmenu = False

        self.show_menu = False
        self.show_menu_time = 0

        self.show_nav = False

        #image scale orig to disp
        self.scale = self.orig[0] / float(self.size[0])
        self.ratio = self.orig[0] / float(self.orig[1])
        #size of raw image in landscape mode
        self.sizel = self.size[0], int(self.orig[1] / self.scale)
        #size of raw image in portrait mode
        self.sizep = int(self.orig[1] / self.scale), self.size[0]

        self.rotation = 0

        self.calc_scale()

        pygame.init()
        pygame.font.init()

        self.screen = pygame.display.set_mode(
            self.size, pygame.FULLSCREEN | pygame.HWSURFACE)
        pygame.display.set_caption("adbmirror")

        self.color = (200, 200, 200)

        font = pygame.font.Font("res/fontawesome.ttf", 70)
        self.img_close = font.render(u'\uf00d', True, self.color)
        self.img_portrait = font.render(u'\uf10b', True, self.color)
        self.img_landscape = pygame.transform.rotate(self.img_portrait, 90)
        self.img_bars = font.render(u'\uf0c9', True, self.color)

        font = pygame.font.Font("res/fontawesome.ttf", 30)
        img_back = font.render(u'\uf053', True, self.color)
        img_home = font.render(u'\uf015', True, self.color)
        img_box = font.render(u'\uf009', True, self.color)

        self.menu_w = int(self.size[0] * MENU_WIDTH / 100.0)
        self.menu_h = int(self.size[1] / 3)
        self.update_menu()

        self.nav_w = int(self.size[0] * NAV_WIDTH / 100.0)

        self.img_nav = pygame.Surface((self.nav_w, self.size[1]))
        self.blit_center(self.img_nav, img_box,
                         (0, 0, self.nav_w, self.menu_h))
        self.blit_center(self.img_nav, img_home,
                         (0, self.menu_h, self.nav_w, self.menu_h))
        self.blit_center(self.img_nav, img_back,
                         (0, self.menu_h * 2, self.nav_w, self.menu_h))
Exemplo n.º 5
0
class Main():
    def __init__(self):
        assert len(sys.argv) == 4
        self.size = map(int, sys.argv[1].split("x"))
        orig = map(int, sys.argv[2].split("x"))
        self.orig = orig[1], orig[0]
        self.path = sys.argv[3]

        self.scalel = True
        self.scalep = False

        self.cap = CapClient(self)
        self.cap.start()

        self.touch = TouchClient(self)
        self.touch.start()

        self.rot = RotationClient()
        self.rot.start()

        self.adb = AdbClient()
        self.adb.start()

        self.mouse_down = False
        self.mouse_time = 0
        self.mouse_inmenu = False

        self.show_menu = False
        self.show_menu_time = 0

        self.show_nav = False

        #image scale orig to disp
        self.scale = self.orig[0] / float(self.size[0])
        self.ratio = self.orig[0] / float(self.orig[1])
        #size of raw image in landscape mode
        self.sizel = self.size[0], int(self.orig[1] / self.scale)
        #size of raw image in portrait mode
        self.sizep = int(self.orig[1] / self.scale), self.size[0]

        self.rotation = 0

        self.calc_scale()

        pygame.init()
        pygame.font.init()

        self.screen = pygame.display.set_mode(
            self.size, pygame.FULLSCREEN | pygame.HWSURFACE)
        pygame.display.set_caption("adbmirror")

        self.color = (200, 200, 200)

        font = pygame.font.Font("res/fontawesome.ttf", 70)
        self.img_close = font.render(u'\uf00d', True, self.color)
        self.img_portrait = font.render(u'\uf10b', True, self.color)
        self.img_landscape = pygame.transform.rotate(self.img_portrait, 90)
        self.img_bars = font.render(u'\uf0c9', True, self.color)

        font = pygame.font.Font("res/fontawesome.ttf", 30)
        img_back = font.render(u'\uf053', True, self.color)
        img_home = font.render(u'\uf015', True, self.color)
        img_box = font.render(u'\uf009', True, self.color)

        self.menu_w = int(self.size[0] * MENU_WIDTH / 100.0)
        self.menu_h = int(self.size[1] / 3)
        self.update_menu()

        self.nav_w = int(self.size[0] * NAV_WIDTH / 100.0)

        self.img_nav = pygame.Surface((self.nav_w, self.size[1]))
        self.blit_center(self.img_nav, img_box,
                         (0, 0, self.nav_w, self.menu_h))
        self.blit_center(self.img_nav, img_home,
                         (0, self.menu_h, self.nav_w, self.menu_h))
        self.blit_center(self.img_nav, img_back,
                         (0, self.menu_h * 2, self.nav_w, self.menu_h))

    def update_menu(self):
        self.img_menu = pygame.Surface((self.menu_w, self.size[1]))

        self.blit_center(self.img_menu, self.img_close,
                         (0, 0, self.menu_w, self.menu_h))
        if self.landscape:
            self.blit_center(self.img_menu, self.img_portrait,
                             (0, self.menu_h, self.menu_w, self.menu_h))
        else:
            self.blit_center(self.img_menu, self.img_landscape,
                             (0, self.menu_h, self.menu_w, self.menu_h))
        self.blit_center(self.img_menu, self.img_bars,
                         (0, self.menu_h * 2, self.menu_w, self.menu_h))

    def calc_scale(self):
        self.landscape = self.rotation in [90, 270]

        if self.show_nav:
            max_w = self.size[0] - self.nav_w
        else:
            max_w = self.size[0]

        if self.landscape:
            x = 0
            w = max_w
            if self.scalel:
                h = self.size[1]
                y = 0
            else:
                h = w / self.ratio
                y = (self.size[1] - h) / 2
        else:
            y = 0
            h = self.size[1]
            if self.scalep:
                x = 0
                w = max_w
            else:
                w = h / self.ratio
                x = (self.size[0] - w) / 2

        self.proj = map(int, [x, y, w, h])
        self.frame_update = True

    def blit_center(self, dst, src, rect):
        x = rect[0] - int((src.get_width() / 2) - (rect[2] / 2))
        y = rect[1] - int((src.get_height() / 2) - (rect[3] / 2))
        dst.blit(src, (x, y))

    def exit(self):
        self.running = False

        self.cap.write(["end"])
        self.touch.write(["end"])
        self.rot.write(["end"])
        self.adb.write(["end"])

    def events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.exit()

            if hasattr(event, "pos"):
                ix, iy = event.pos
                self.mouse_inmenu = ix <= self.size[1] * MENU_BORDER / 100.0

                fx = min(max(0, (ix - self.proj[0]) / float(self.proj[2])), 1)
                fy = min(max(0, (iy - self.proj[1]) / float(self.proj[3])), 1)

                if self.rotation == 0:
                    x = fx
                    y = fy

                if self.rotation == 90:
                    x = 1.0 - fy
                    y = fx

                if self.rotation == 180:
                    x = 1.0 - fx
                    y = 1.0 - fy

                if self.rotation == 270:
                    x = fy
                    y = 1.0 - fx

            if hasattr(event, "button"):
                if event.button is not 1:
                    continue

                if event.type == pygame.MOUSEBUTTONDOWN:
                    if ix < self.menu_w and self.show_menu:
                        self.menu_action(iy / (self.size[1] / 3))
                    elif ix > self.size[0] - self.nav_w and self.show_nav:
                        self.nav_action(iy / (self.size[1] / 3))
                    else:
                        self.touch.write(["down", x, y])
                        self.mouse_down = True
                        self.mouse_time = time()

                if event.type == pygame.MOUSEBUTTONUP:
                    self.touch.write(["up"])
                    self.mouse_down = False

            if event.type == pygame.MOUSEMOTION:
                if self.mouse_down:
                    self.touch.write(["move", x, y])

    def nav_action(self, but):
        if but == 0:
            self.adb.write(["apps"])
        if but == 1:
            self.adb.write(["home"])
        if but == 2:
            self.adb.write(["back"])

    def menu_action(self, but):
        if but == 0:
            self.exit()
        if but == 1:
            if self.landscape:
                self.adb.write(["portrait"])
            else:
                self.adb.write(["landscape"])
        if but == 2:
            self.show_nav = not self.show_nav
            self.calc_scale()

        self.show_menu = False

    def menu_loop(self):
        if self.mouse_down and time(
        ) - self.mouse_time > MENU_TAP and self.mouse_inmenu:
            self.show_menu = True
            self.screen_update = True
            self.show_menu_time = time()

        if self.show_menu and time() - self.show_menu_time > MENU_TIMEOUT:
            self.show_menu = False
            self.screen_update = True

    def run(self):
        self.running = True
        self.adb.write(["landscape"])

        self.screen_update = True
        self.frame_update = False

        frame_cache = pygame.Surface(self.size)
        last_frame = None

        while self.running:
            self.events()

            for msg in self.rot.read():
                cmd = msg[0]
                if cmd == "rot":
                    self.rotation = msg[1]
                    self.calc_scale()
                    self.update_menu()

            #we will process only one frame at the time
            msgs = self.cap.read()
            msgl = len(msgs)
            if msgl:
                msg = msgs[msgl - 1]
                cmd = msg[0]

                if cmd == "data":
                    data = cStringIO.StringIO(msg[1])
                    last_frame = pygame.image.load(data)
                    self.frame_update = True

            for msg in self.adb.read():
                cmd = msg[0]
                if cmd == "end":
                    self.exit()

            self.menu_loop()

            if self.frame_update:
                self.frame_update = False

                if last_frame is not None:
                    if self.landscape:
                        a = last_frame.subsurface(
                            pygame.Rect((0, 0), self.sizel))
                    else:
                        a = last_frame.subsurface(
                            pygame.Rect((0, 0), self.sizep))

                    aw, ah = a.get_size()
                    if aw != self.proj[2] or ah != self.proj[3]:
                        frame_cache = pygame.transform.smoothscale(
                            a, (self.proj[2], self.proj[3]))
                    else:
                        frame_cache = a.copy()

                self.screen_update = True

            if self.screen_update:
                self.screen.fill((0, 0, 0))
                self.screen_update = False
                self.screen.blit(frame_cache, (self.proj[0], self.proj[1]))
                if self.show_menu:
                    self.screen.blit(self.img_menu, (0, 0))
                if self.show_nav:
                    self.screen.blit(self.img_nav,
                                     (self.size[0] - self.nav_w, 0))
                pygame.display.update()
Exemplo n.º 6
0
class Main():
    def __init__(self):
        assert len(sys.argv) == 4
        self.size = map(int, sys.argv[1].split("x"))
        orig = map(int, sys.argv[2].split("x"))
        self.orig = orig[1], orig[0]
        self.path = sys.argv[3]

        self.scalel = True
        self.scalep = False

        ml = self.orig[0] / float(self.size[0])
        self.sizel = self.size[0], int(self.orig[1] / ml)
        self.yl = (self.size[1] - self.sizel[1]) / 2

        mp = self.orig[0] / float(self.size[1])
        self.sizep = int(self.orig[1] / mp), self.size[1]
        self.xp = int((self.size[0] - self.sizep[0]) / 2)

        self.screen = pygame.display.set_mode(self.size)

        self.cap = CapClient(self)
        self.cap.start()

        self.touch = TouchClient(self)
        self.touch.start()

        self.rot = RotationClient()
        self.rot.start()

        self.mouse_down = False

    def events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.running = False
                self.cap.write(["end"])
                self.touch.write(["end"])
                self.rot.write(["end"])

            if hasattr(event, "pos"):
                ix, iy = event.pos
                if self.rotation == 90:
                    y = (ix / float(self.size[0]))
                    if self.scalel:
                        x = 1.0 - (iy / float(self.size[1]))
                    else:
                        x = 1.0 - (((iy - self.yl)) / float(self.sizel[1]))

                if self.rotation == 270:
                    y = 1.0 - (ix / float(self.size[0]))
                    if self.scalel:
                        x = (iy / float(self.size[1]))
                    else:
                        x = (((iy - self.yl)) / float(self.sizel[1]))

                if self.rotation == 0:
                    y = iy / float(self.size[1])
                    if self.scalep:
                        x = ix / float(self.size[0])
                    else:
                        x = ((ix - self.xp)) / float(self.sizep[0])

                if self.rotation == 180:
                    y = 1.0 - (iy / float(self.size[1]))
                    if self.scalep:
                        x = 1.0 - (ix / float(self.size[0]))
                    else:
                        x = 1.0 - (((ix - self.xp)) / float(self.sizep[0]))

                x = min(max(0, x), 1)
                y = min(max(0, y), 1)
#                 print x, y

            if hasattr(event, "button"):
                if event.button is not 1:
                    continue

                if event.type == pygame.MOUSEBUTTONDOWN:
                    self.touch.write(["down", x, y])
                    self.mouse_down = True

                if event.type == pygame.MOUSEBUTTONUP:
                    self.touch.write(["up"])
                    self.mouse_down = False

            if event.type == pygame.MOUSEMOTION:
                if self.mouse_down:
                    self.touch.write(["move", x, y])


#             if event.type == pygame.

    def run(self):
        self.running = True
        self.landscape = None
        self.rotation = 0

        while self.running:
            self.events()

            for msg in self.rot.read():
                cmd = msg[0]
                if cmd == "rot":
                    self.rotation = msg[1]
                    self.screen.fill((0, 0, 0))

            for msg in self.cap.read():
                cmd = msg[0]
                if cmd == "head":
                    self.banner = msg[1]

                if cmd == "data":
                    data = cStringIO.StringIO(msg[1])
                    a = pygame.image.load(data)

                    landscape = self.rotation in [90, 270]

                    if landscape:
                        if self.scalel:
                            a = a.subsurface(pygame.Rect((0, 0), self.sizel))
                            a = pygame.transform.smoothscale(a, self.size)
                            y = 0
                        else:
                            y = self.yl
                        self.screen.blit(a, (0, y))
                    else:
                        a = pygame.transform.smoothscale(
                            a, (self.size[1], self.size[1]))
                        if self.scalep:
                            a = a.subsurface(pygame.Rect((0, 0), self.sizep))
                            a = pygame.transform.smoothscale(a, self.size)
                            x = 0
                        else:
                            x = self.xp
                        self.screen.blit(a, (x, 0))

                    pygame.display.update()
Exemplo n.º 7
0
class Main():
    def __init__(self):
        assert len(sys.argv) == 4
        self.size = list(map(int, sys.argv[1].split("x")))
        orig = list(map(int, sys.argv[2].split("x")))
        self.orig = orig[0], orig[1]
        self.path = sys.argv[3]

        self.cap = CapClient(self)
        self.cap.start()
        self.touch = TouchClient(self)
        self.touch.max_x = orig[0]
        self.touch.max_y = orig[1]
        self.touch.start()

        self.mouse_down = False
        self.mouse_pos = (0, 0)

        self.scale = self.orig[0] / float(self.size[0])
        self.ratio = self.orig[1] / float(self.orig[0])
        print('Scale, ratio:', self.scale, self.ratio)

        self.sizep = self.size[0], int(self.orig[1] / self.scale)
        self.sizel = int(self.orig[1] / self.scale), self.size[0]
        print('Raw image size l/p:', self.sizel, self.sizep)

        self.rotation = 0
        self.calc_scale()

        pygame.init()
        pygame.font.init()
        self.screen = pygame.display.set_mode(self.size)

    def calc_scale(self):
        self.landscape = self.rotation in [90, 270]
        max_w = self.size[0]
        if self.landscape:
            x = 0
            w = max_w
            h = w / self.ratio
            y = (self.size[1] - h) / 2
        else:
            y = 0
            h = self.size[1]
            w = h / self.ratio
            x = (self.size[0] - w) / 2

        self.proj = list(map(int, [x, y, w, h]))
        print('Projection:', self.proj)
        self.frame_update = True

    def blit_center(self, dst, src, rect):
        x = rect[0] - int((src.get_width() / 2) - (rect[2] / 2))
        y = rect[1] - int((src.get_height() / 2) - (rect[3] / 2))
        dst.blit(src, (x, y))

    def exit(self):
        self.running = False
        self.cap.write(["end"])
        self.touch.write(["end"])

    def events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.exit()

            if hasattr(event, "pos"):
                ix, iy = event.pos
                fx = min(max(0, (ix - self.proj[0]) / float(self.proj[2])), 1)
                fy = min(max(0, (iy - self.proj[1]) / float(self.proj[3])), 1)
                if self.rotation == 0:
                    x = fx
                    y = fy
                if self.rotation == 90:
                    x = 1.0 - fy
                    y = fx
                if self.rotation == 180:
                    x = 1.0 - fx
                    y = 1.0 - fy
                if self.rotation == 270:
                    x = fy
                    y = 1.0 - fx
                pygame.display.set_caption(str(x) + '  -  ' + str(y))

            if hasattr(event, "button"):
                if event.button is 1:
                    if event.type == pygame.MOUSEBUTTONDOWN:
                        self.touch.write(["down", x, y])
                        self.mouse_down = True
                    if event.type == pygame.MOUSEBUTTONUP:
                        self.touch.write(["up"])
                        self.mouse_down = False
                if event.button is 2:  # middle
                    if event.type == pygame.MOUSEBUTTONUP:
                        os.system("adb shell input keyevent 3")
                if event.button is 3:  # right
                    if event.type == pygame.MOUSEBUTTONUP:
                        os.system("adb shell input keyevent 4")

            if event.type == pygame.MOUSEMOTION:
                if self.mouse_down:
                    self.touch.write(["move", x, y])
                    self.mouse_pos = (x, y)

            if event.type == pygame.KEYDOWN:
                if event.unicode == 's':
                    fn = str(int(round(time() * 1000)))
                    pygame.image.save(self.frame_cache, fn + ".png")
                    print("screenshot saved.")

                if event.unicode == 'q':
                    self.exit()
                    pygame.quit()
                    exit()

    def run(self):
        self.running = True
        self.screen_update = True
        self.frame_update = False
        self.frame_cache = pygame.Surface(self.size)
        last_frame = None

        while self.running:
            self.events()

            msgs = self.cap.read()
            msgl = len(msgs)
            if msgl:
                msg = msgs[msgl - 1]
                cmd = msg[0]
                if cmd == "data":
                    last_frame = pygame.image.load(BytesIO(msg[1]))
                    self.frame_update = True

            if self.frame_update:
                self.frame_update = False
                if last_frame is not None:
                    if self.landscape:
                        a = last_frame.subsurface(
                            pygame.Rect((0, 0), self.sizel))
                    else:
                        a = last_frame.subsurface(
                            pygame.Rect((0, 0), self.sizep))
                    aw, ah = a.get_size()
                    if aw != self.proj[2] or ah != self.proj[3]:
                        self.frame_cache = pygame.transform.smoothscale(
                            a, (self.proj[2], self.proj[3]))
                    else:
                        self.frame_cache = a.copy()
                self.screen_update = True

            if self.screen_update:
                self.screen.fill((0, 0, 0))
                self.screen_update = False
                self.screen.blit(self.frame_cache,
                                 (self.proj[0], self.proj[1]))
                pygame.display.update()
Exemplo n.º 8
0
class Main():
    def __init__(self):
        assert len(sys.argv) == 4
        self.rotation = 0  # or 90 for landscape
        self.winrotation = self.rotation
        p_size = list(map(int, sys.argv[1].split("x")))
        p_orig = list(map(int, sys.argv[2].split("x")))

        self.size = p_size[0], p_size[1]
        self.orig = p_orig[0], p_orig[1]
        # My Add
        if self.winrotation in [90, 270]:
            self.size = p_size[1], p_size[0]
            self.orig = p_orig[1], p_orig[0]

        self.path = sys.argv[3]

        self.cap = CapClient(self)
        self.cap.start()
        self.touch = TouchClient(self)
        self.touch.start()

        self.mouse_down = False
        self.mouse_pos = (0, 0)

        self.scale = self.orig[0] / float(self.size[0])
        self.ratio = self.orig[1] / float(self.orig[0])
        print('Scale, ratio:', self.scale, self.ratio)

        self.sizep = self.size[0], int(self.orig[1] / self.scale)
        self.sizel = int(self.orig[1] / self.scale), self.size[0]
        print('Raw image size l/p:', self.sizel, self.sizep)

        #self.rotation = 0 # Mii: 0, 90, 270 == NG
        self.calc_scale()
        self.state_str = '-Start-'

        pygame.init()
        pygame.font.init()
        # pygame.key.set_repeat(delay, interval)
        pygame.key.set_repeat(30, 30)

        self.screen = pygame.display.set_mode(self.size)

    def calc_scale(self):
        self.landscape = self.rotation in [90, 270]
        if self.winrotation in [90, 270]:
            self.landscape = self.rotation in [0, 180]
        max_w = self.size[0]
        if self.landscape:  # == 270 or self.landscape == 90:
            x = 0
            w = max_w
            h = w / self.ratio
            y = (self.size[1] - h) / 2
        else:  # self.landscape == 180 or self.landscape == 0:
            y = 0
            h = self.size[1]
            w = h / self.ratio
            x = (self.size[0] - w) / 2

        self.proj = list(map(int, [x, y, w, h]))
        print('Projection:', self.proj)
        self.frame_update = True

    def blit_center(self, dst, src, rect):
        x = rect[0] - int((src.get_width() / 2) - (rect[2] / 2))
        y = rect[1] - int((src.get_height() / 2) - (rect[3] / 2))
        dst.blit(src, (x, y))

    def exit(self):
        self.running = False
        self.cap.write(["end"])
        self.touch.write(["end"])

    def save_image(self, img, fn):
        img.save(fn, "PNG")

    def events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.exit()

            if hasattr(event, "pos"):
                ix, iy = event.pos
                fx = min(max(0, (ix - self.proj[0]) / float(self.proj[2])), 1)
                fy = min(max(0, (iy - self.proj[1]) / float(self.proj[3])), 1)
                if self.rotation == 0:
                    x = fx
                    y = fy
                if self.rotation == 90:
                    x = 1.0 - fy
                    y = fx
                if self.rotation == 180:
                    x = 1.0 - fx
                    y = 1.0 - fy
                if self.rotation == 270:
                    x = fy
                    y = 1.0 - fx

                pygame.display.set_caption(str(x) + self.state_str + str(y))

            if hasattr(event, "button"):
                if event.button is not 1:
                    continue
                if event.type == pygame.MOUSEBUTTONDOWN:
                    self.touch.write(["down", x, y, 0])
                    self.mouse_down = True
                if event.type == pygame.MOUSEBUTTONUP:
                    self.touch.write(["up", 0])
                    self.mouse_down = False

            if event.type == pygame.MOUSEMOTION:
                if self.mouse_down:
                    self.touch.write(["move", x, y, 0])
                    self.mouse_pos = (x, y)

            if event.type == pygame.KEYUP:
                if (event.key not in [
                        pygame.K_w, pygame.K_a, pygame.K_s, pygame.K_d
                ]):
                    self.touch.write(["up", 0])
                    self.mouse_down = False
                elif (event.key == pygame.K_RCTRL):
                    self.state_str = '=Auto='
                elif (event.key == pygame.K_SPACE):
                    self.state_str = '=Stop='
                else:
                    pass

    def run(self):
        self.running = True
        self.screen_update = True
        self.frame_update = False
        self.frame_cache = pygame.Surface(self.size)
        last_frame = None

        while self.running:
            self.events()

            msgs = self.cap.read()
            msgl = len(msgs)
            if msgl:
                msg = msgs[msgl - 1]
                cmd = msg[0]
                if cmd == "data":
                    last_frame = pygame.image.load(BytesIO(msg[1]))
                    self.frame_update = True

            if self.frame_update:
                self.frame_update = False
                if last_frame is not None:
                    if self.landscape:
                        a = last_frame.subsurface(
                            pygame.Rect((0, 0), self.sizel))
                    else:
                        a = last_frame.subsurface(
                            pygame.Rect((0, 0), self.sizep))
                    aw, ah = a.get_size()
                    if aw != self.proj[2] or ah != self.proj[3]:
                        self.frame_cache = pygame.transform.smoothscale(
                            a, (self.proj[2], self.proj[3]))
                    else:
                        self.frame_cache = a.copy()
                self.screen_update = True

            if self.screen_update:
                self.screen.fill((0, 0, 0))
                self.screen_update = False
                self.screen.blit(self.frame_cache,
                                 (self.proj[0], self.proj[1]))
                pygame.display.update()