Generated by Cython 0.28.5

Yellow lines hint at Python interaction.
Click on a line that starts with a "+" to see the C code that Cython generated for it.

Raw output: motion.c

 001: # -*- coding: utf-8 -*-
 002: # This file is part of Xpra.
 003: # Copyright (C) 2016-2017 Antoine Martin <antoine@devloop.org.uk>
 004: # Xpra is released under the terms of the GNU GPL v2, or, at your option, any
 005: # later version. See the file COPYING for details.
 006: 
 007: #!python
 008: #cython: auto_pickle=False, boundscheck=False, wraparound=False, cdivision=True
 009: from __future__ import absolute_import
 010: 
+011: import os
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_os, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 11, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_os, __pyx_t_1) < 0) __PYX_ERR(0, 11, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+012: import time
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_time, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 12, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_time, __pyx_t_1) < 0) __PYX_ERR(0, 12, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+013: import struct
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_struct, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 13, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_struct, __pyx_t_1) < 0) __PYX_ERR(0, 13, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+014: import collections
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_collections, 0, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 14, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_collections, __pyx_t_1) < 0) __PYX_ERR(0, 14, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 015: 
+016: from xpra.util import envbool, repr_ellipsized, csv
  __pyx_t_1 = PyList_New(3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_INCREF(__pyx_n_s_envbool);
  __Pyx_GIVEREF(__pyx_n_s_envbool);
  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_envbool);
  __Pyx_INCREF(__pyx_n_s_repr_ellipsized);
  __Pyx_GIVEREF(__pyx_n_s_repr_ellipsized);
  PyList_SET_ITEM(__pyx_t_1, 1, __pyx_n_s_repr_ellipsized);
  __Pyx_INCREF(__pyx_n_s_csv);
  __Pyx_GIVEREF(__pyx_n_s_csv);
  PyList_SET_ITEM(__pyx_t_1, 2, __pyx_n_s_csv);
  __pyx_t_2 = __Pyx_Import(__pyx_n_s_xpra_util, __pyx_t_1, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_envbool); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_envbool, __pyx_t_1) < 0) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_repr_ellipsized); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_repr_ellipsized, __pyx_t_1) < 0) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_csv); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_csv, __pyx_t_1) < 0) __PYX_ERR(0, 16, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+017: from xpra.log import Logger
  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 17, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_INCREF(__pyx_n_s_Logger);
  __Pyx_GIVEREF(__pyx_n_s_Logger);
  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_Logger);
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_xpra_log, __pyx_t_2, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 17, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_Logger); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 17, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_Logger, __pyx_t_2) < 0) __PYX_ERR(0, 17, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+018: log = Logger("encoding", "scroll")
  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_Logger); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 18, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__4, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 18, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_log, __pyx_t_2) < 0) __PYX_ERR(0, 18, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
/* … */
  __pyx_tuple__4 = PyTuple_Pack(2, __pyx_n_s_encoding, __pyx_n_s_scroll); if (unlikely(!__pyx_tuple__4)) __PYX_ERR(0, 18, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__4);
  __Pyx_GIVEREF(__pyx_tuple__4);
 019: 
 020: from xpra.buffers.membuf cimport memalign, object_as_buffer, xxh64
+021: from xpra.server.window.region import rectangle
  __pyx_t_2 = PyList_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 21, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_INCREF(__pyx_n_s_rectangle);
  __Pyx_GIVEREF(__pyx_n_s_rectangle);
  PyList_SET_ITEM(__pyx_t_2, 0, __pyx_n_s_rectangle);
  __pyx_t_1 = __Pyx_Import(__pyx_n_s_xpra_server_window_region, __pyx_t_2, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 21, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_ImportFrom(__pyx_t_1, __pyx_n_s_rectangle); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 21, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_rectangle, __pyx_t_2) < 0) __PYX_ERR(0, 21, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 022: 
 023: 
+024: cdef int DEBUG = envbool("XPRA_SCROLL_DEBUG", False)
  __pyx_t_1 = __Pyx_GetModuleGlobalName(__pyx_n_s_envbool); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 24, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_tuple__5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 24, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_3 = __Pyx_PyInt_As_int(__pyx_t_2); if (unlikely((__pyx_t_3 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 24, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_4xpra_6server_6window_6motion_DEBUG = __pyx_t_3;
/* … */
  __pyx_tuple__5 = PyTuple_Pack(2, __pyx_n_s_XPRA_SCROLL_DEBUG, Py_False); if (unlikely(!__pyx_tuple__5)) __PYX_ERR(0, 24, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__5);
  __Pyx_GIVEREF(__pyx_tuple__5);
 025: 
 026: 
 027: from libc.stdint cimport uint8_t, uint16_t, int16_t, uint64_t, uintptr_t
 028: 
 029: cdef extern from "stdlib.h":
 030:     void* malloc(size_t __size)
 031: 
 032: cdef extern from "string.h":
 033:     void free(void * ptr) nogil
 034:     void *memset(void * ptr, int value, size_t num) nogil
 035:     void *memcpy(void * destination, void * source, size_t num) nogil
 036: 
 037: 
 038: DEF MIN_LINE_COUNT = 5
 039: 
 040: DEF MAXINT64 = 2**63
 041: DEF MAXUINT64 = 2**64
 042: DEF MASK64 = 2**64-1
 043: 
+044: def h(v):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_1h(PyObject *__pyx_self, PyObject *__pyx_v_v); /*proto*/
static PyMethodDef __pyx_mdef_4xpra_6server_6window_6motion_1h = {"h", (PyCFunction)__pyx_pw_4xpra_6server_6window_6motion_1h, METH_O, 0};
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_1h(PyObject *__pyx_self, PyObject *__pyx_v_v) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("h (wrapper)", 0);
  __pyx_r = __pyx_pf_4xpra_6server_6window_6motion_h(__pyx_self, ((PyObject *)__pyx_v_v));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_6window_6motion_h(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_v) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("h", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_AddTraceback("xpra.server.window.motion.h", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__6 = PyTuple_Pack(1, __pyx_n_s_v); if (unlikely(!__pyx_tuple__6)) __PYX_ERR(0, 44, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__6);
  __Pyx_GIVEREF(__pyx_tuple__6);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_4xpra_6server_6window_6motion_1h, NULL, __pyx_n_s_xpra_server_window_motion); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 44, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_h, __pyx_t_2) < 0) __PYX_ERR(0, 44, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+045:     return hex(v).lstrip("0x").rstrip("L")
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_builtin_hex, __pyx_v_v); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 45, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_lstrip); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 45, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple_, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 45, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_n_s_rstrip); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 45, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
/* … */
  __pyx_tuple_ = PyTuple_Pack(1, __pyx_kp_s_0x); if (unlikely(!__pyx_tuple_)) __PYX_ERR(0, 45, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple_);
  __Pyx_GIVEREF(__pyx_tuple_);
  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_tuple__2, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 45, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;
  __pyx_tuple__2 = PyTuple_Pack(1, __pyx_n_s_L); if (unlikely(!__pyx_tuple__2)) __PYX_ERR(0, 45, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__2);
  __Pyx_GIVEREF(__pyx_tuple__2);
 046: 
+047: cdef inline uint64_t hashtoint64(s):
static CYTHON_INLINE uint64_t __pyx_f_4xpra_6server_6window_6motion_hashtoint64(PyObject *__pyx_v_s) {
  uint64_t __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("hashtoint64", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_WriteUnraisable("xpra.server.window.motion.hashtoint64", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
  __pyx_r = 0;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
static PyObject *__pyx_gb_4xpra_6server_6window_6motion_2da_2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
+048:     return <uint64_t> struct.unpack("@L", s)[0]
  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_struct); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 48, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_unpack); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 48, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = NULL;
  __pyx_t_4 = 0;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_2)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_2);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
      __pyx_t_4 = 1;
    }
  }
  #if CYTHON_FAST_PYCALL
  if (PyFunction_Check(__pyx_t_3)) {
    PyObject *__pyx_temp[3] = {__pyx_t_2, __pyx_kp_s_L_2, __pyx_v_s};
    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_4, 2+__pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 48, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_GOTREF(__pyx_t_1);
  } else
  #endif
  #if CYTHON_FAST_PYCCALL
  if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
    PyObject *__pyx_temp[3] = {__pyx_t_2, __pyx_kp_s_L_2, __pyx_v_s};
    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_4, 2+__pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 48, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_GOTREF(__pyx_t_1);
  } else
  #endif
  {
    __pyx_t_5 = PyTuple_New(2+__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 48, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    if (__pyx_t_2) {
      __Pyx_GIVEREF(__pyx_t_2); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_2); __pyx_t_2 = NULL;
    }
    __Pyx_INCREF(__pyx_kp_s_L_2);
    __Pyx_GIVEREF(__pyx_kp_s_L_2);
    PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_4, __pyx_kp_s_L_2);
    __Pyx_INCREF(__pyx_v_s);
    __Pyx_GIVEREF(__pyx_v_s);
    PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_4, __pyx_v_s);
    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 48, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_GetItemInt(__pyx_t_1, 0, long, 1, __Pyx_PyInt_From_long, 0, 0, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 48, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_6 = __Pyx_PyInt_As_uint64_t(__pyx_t_3); if (unlikely((__pyx_t_6 == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 48, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_r = ((uint64_t)__pyx_t_6);
  goto __pyx_L0;
 049: 
+050: cdef da(uint64_t *a, uint16_t l):
static PyObject *__pyx_f_4xpra_6server_6window_6motion_da(uint64_t *__pyx_v_a, uint16_t __pyx_v_l) {
  struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct____pyx_f_4xpra_6server_6window_6motion_da *__pyx_cur_scope;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("da", 0);
  __pyx_cur_scope = (struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct____pyx_f_4xpra_6server_6window_6motion_da *)__pyx_tp_new_4xpra_6server_6window_6motion___pyx_scope_struct____pyx_f_4xpra_6server_6window_6motion_da(__pyx_ptype_4xpra_6server_6window_6motion___pyx_scope_struct____pyx_f_4xpra_6server_6window_6motion_da, __pyx_empty_tuple, NULL);
  if (unlikely(!__pyx_cur_scope)) {
    __pyx_cur_scope = ((struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct____pyx_f_4xpra_6server_6window_6motion_da *)Py_None);
    __Pyx_INCREF(Py_None);
    __PYX_ERR(0, 50, __pyx_L1_error)
  } else {
    __Pyx_GOTREF(__pyx_cur_scope);
  }
  __pyx_cur_scope->__pyx_v_a = __pyx_v_a;
  __pyx_cur_scope->__pyx_v_l = __pyx_v_l;
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_AddTraceback("xpra.server.window.motion.da", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = 0;
  __pyx_L0:;
  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
static PyObject *__pyx_gb_4xpra_6server_6window_6motion_2dd_2generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value); /* proto */
/* … */
struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct____pyx_f_4xpra_6server_6window_6motion_da {
  PyObject_HEAD
  uint64_t *__pyx_v_a;
  uint16_t __pyx_v_l;
};

+051:     return repr_ellipsized(csv(h(a[i]) for i in range(l)))
static PyObject *__pyx_pf_4xpra_6server_6window_6motion_2da_genexpr(PyObject *__pyx_self) {
  struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct_1_genexpr *__pyx_cur_scope;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("genexpr", 0);
  __pyx_cur_scope = (struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct_1_genexpr *)__pyx_tp_new_4xpra_6server_6window_6motion___pyx_scope_struct_1_genexpr(__pyx_ptype_4xpra_6server_6window_6motion___pyx_scope_struct_1_genexpr, __pyx_empty_tuple, NULL);
  if (unlikely(!__pyx_cur_scope)) {
    __pyx_cur_scope = ((struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct_1_genexpr *)Py_None);
    __Pyx_INCREF(Py_None);
    __PYX_ERR(0, 51, __pyx_L1_error)
  } else {
    __Pyx_GOTREF(__pyx_cur_scope);
  }
  __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct____pyx_f_4xpra_6server_6window_6motion_da *) __pyx_self;
  __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
  {
    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_4xpra_6server_6window_6motion_2da_2generator, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_da_locals_genexpr, __pyx_n_s_xpra_server_window_motion); if (unlikely(!gen)) __PYX_ERR(0, 51, __pyx_L1_error)
    __Pyx_DECREF(__pyx_cur_scope);
    __Pyx_RefNannyFinishContext();
    return (PyObject *) gen;
  }

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_AddTraceback("xpra.server.window.motion.da.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_gb_4xpra_6server_6window_6motion_2da_2generator(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */
{
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("genexpr", 0);
  __pyx_L3_first_run:;
  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 51, __pyx_L1_error)
  __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_l;
  __pyx_t_2 = __pyx_t_1;
  for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
    __pyx_cur_scope->__pyx_v_i = __pyx_t_3;
    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_h); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 51, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_6 = __Pyx_PyInt_From_uint64_t((__pyx_cur_scope->__pyx_outer_scope->__pyx_v_a[__pyx_cur_scope->__pyx_v_i])); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 51, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_7 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
      if (likely(__pyx_t_7)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_7);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_5, function);
      }
    }
    if (!__pyx_t_7) {
      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 51, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_4);
    } else {
      #if CYTHON_FAST_PYCALL
      if (PyFunction_Check(__pyx_t_5)) {
        PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 51, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      } else
      #endif
      #if CYTHON_FAST_PYCCALL
      if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
        PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 51, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      } else
      #endif
      {
        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 51, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_8);
        __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
        __Pyx_GIVEREF(__pyx_t_6);
        PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
        __pyx_t_6 = 0;
        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 51, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      }
    }
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_r = __pyx_t_4;
    __pyx_t_4 = 0;
    __pyx_cur_scope->__pyx_t_0 = __pyx_t_1;
    __pyx_cur_scope->__pyx_t_1 = __pyx_t_2;
    __pyx_cur_scope->__pyx_t_2 = __pyx_t_3;
    __Pyx_XGIVEREF(__pyx_r);
    __Pyx_RefNannyFinishContext();
    __Pyx_Coroutine_ResetAndClearException(__pyx_generator);
    /* return from generator, yielding value */
    __pyx_generator->resume_label = 1;
    return __pyx_r;
    __pyx_L6_resume_from_yield:;
    __pyx_t_1 = __pyx_cur_scope->__pyx_t_0;
    __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
    __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 51, __pyx_L1_error)
  }
  CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope);

  /* function exit code */
  PyErr_SetNone(PyExc_StopIteration);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_r); __pyx_r = 0;
  __Pyx_Coroutine_ResetAndClearException(__pyx_generator);
  __pyx_generator->resume_label = -1;
  __Pyx_Coroutine_clear((PyObject*)__pyx_generator);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_repr_ellipsized); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 51, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_csv); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 51, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __pyx_pf_4xpra_6server_6window_6motion_2da_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 51, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_6 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
    if (likely(__pyx_t_6)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_4, function);
    }
  }
  if (!__pyx_t_6) {
    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 51, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __Pyx_GOTREF(__pyx_t_3);
  } else {
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_4)) {
      PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
      __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 51, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
      PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
      __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 51, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    } else
    #endif
    {
      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 51, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __pyx_t_6 = NULL;
      __Pyx_GIVEREF(__pyx_t_5);
      PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
      __pyx_t_5 = 0;
      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 51, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    }
  }
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
    if (likely(__pyx_t_4)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_4);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_2, function);
    }
  }
  if (!__pyx_t_4) {
    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_GOTREF(__pyx_t_1);
  } else {
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_2)) {
      PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_3};
      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
      PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_3};
      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    } else
    #endif
    {
      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 51, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
      __Pyx_GIVEREF(__pyx_t_3);
      PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_3);
      __pyx_t_3 = 0;
      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    }
  }
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;
/* … */
struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct_1_genexpr {
  PyObject_HEAD
  struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct____pyx_f_4xpra_6server_6window_6motion_da *__pyx_outer_scope;
  uint16_t __pyx_v_i;
  uint16_t __pyx_t_0;
  uint16_t __pyx_t_1;
  uint16_t __pyx_t_2;
};

 052: 
+053: cdef dd(uint16_t *d, uint16_t l):
static PyObject *__pyx_f_4xpra_6server_6window_6motion_dd(uint16_t *__pyx_v_d, uint16_t __pyx_v_l) {
  struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct_2___pyx_f_4xpra_6server_6window_6motion_dd *__pyx_cur_scope;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("dd", 0);
  __pyx_cur_scope = (struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct_2___pyx_f_4xpra_6server_6window_6motion_dd *)__pyx_tp_new_4xpra_6server_6window_6motion___pyx_scope_struct_2___pyx_f_4xpra_6server_6window_6motion_dd(__pyx_ptype_4xpra_6server_6window_6motion___pyx_scope_struct_2___pyx_f_4xpra_6server_6window_6motion_dd, __pyx_empty_tuple, NULL);
  if (unlikely(!__pyx_cur_scope)) {
    __pyx_cur_scope = ((struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct_2___pyx_f_4xpra_6server_6window_6motion_dd *)Py_None);
    __Pyx_INCREF(Py_None);
    __PYX_ERR(0, 53, __pyx_L1_error)
  } else {
    __Pyx_GOTREF(__pyx_cur_scope);
  }
  __pyx_cur_scope->__pyx_v_d = __pyx_v_d;
  __pyx_cur_scope->__pyx_v_l = __pyx_v_l;
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_AddTraceback("xpra.server.window.motion.dd", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = 0;
  __pyx_L0:;
  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct_2___pyx_f_4xpra_6server_6window_6motion_dd {
  PyObject_HEAD
  uint16_t *__pyx_v_d;
  uint16_t __pyx_v_l;
};

+054:     return repr_ellipsized(csv(h(d[i]) for i in range(l)))
static PyObject *__pyx_pf_4xpra_6server_6window_6motion_2dd_genexpr(PyObject *__pyx_self) {
  struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct_3_genexpr *__pyx_cur_scope;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("genexpr", 0);
  __pyx_cur_scope = (struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct_3_genexpr *)__pyx_tp_new_4xpra_6server_6window_6motion___pyx_scope_struct_3_genexpr(__pyx_ptype_4xpra_6server_6window_6motion___pyx_scope_struct_3_genexpr, __pyx_empty_tuple, NULL);
  if (unlikely(!__pyx_cur_scope)) {
    __pyx_cur_scope = ((struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct_3_genexpr *)Py_None);
    __Pyx_INCREF(Py_None);
    __PYX_ERR(0, 54, __pyx_L1_error)
  } else {
    __Pyx_GOTREF(__pyx_cur_scope);
  }
  __pyx_cur_scope->__pyx_outer_scope = (struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct_2___pyx_f_4xpra_6server_6window_6motion_dd *) __pyx_self;
  __Pyx_INCREF(((PyObject *)__pyx_cur_scope->__pyx_outer_scope));
  __Pyx_GIVEREF(__pyx_cur_scope->__pyx_outer_scope);
  {
    __pyx_CoroutineObject *gen = __Pyx_Generator_New((__pyx_coroutine_body_t) __pyx_gb_4xpra_6server_6window_6motion_2dd_2generator1, NULL, (PyObject *) __pyx_cur_scope, __pyx_n_s_genexpr, __pyx_n_s_dd_locals_genexpr, __pyx_n_s_xpra_server_window_motion); if (unlikely(!gen)) __PYX_ERR(0, 54, __pyx_L1_error)
    __Pyx_DECREF(__pyx_cur_scope);
    __Pyx_RefNannyFinishContext();
    return (PyObject *) gen;
  }

  /* function exit code */
  __pyx_L1_error:;
  __Pyx_AddTraceback("xpra.server.window.motion.dd.genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __Pyx_DECREF(((PyObject *)__pyx_cur_scope));
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_gb_4xpra_6server_6window_6motion_2dd_2generator1(__pyx_CoroutineObject *__pyx_generator, CYTHON_UNUSED PyThreadState *__pyx_tstate, PyObject *__pyx_sent_value) /* generator body */
{
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("genexpr", 0);
  __pyx_L3_first_run:;
  if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 54, __pyx_L1_error)
  __pyx_t_1 = __pyx_cur_scope->__pyx_outer_scope->__pyx_v_l;
  __pyx_t_2 = __pyx_t_1;
  for (__pyx_t_3 = 0; __pyx_t_3 < __pyx_t_2; __pyx_t_3+=1) {
    __pyx_cur_scope->__pyx_v_i = __pyx_t_3;
    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_h); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 54, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_6 = __Pyx_PyInt_From_uint16_t((__pyx_cur_scope->__pyx_outer_scope->__pyx_v_d[__pyx_cur_scope->__pyx_v_i])); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 54, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_7 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
      if (likely(__pyx_t_7)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_7);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_5, function);
      }
    }
    if (!__pyx_t_7) {
      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_t_6); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 54, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_4);
    } else {
      #if CYTHON_FAST_PYCALL
      if (PyFunction_Check(__pyx_t_5)) {
        PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 54, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      } else
      #endif
      #if CYTHON_FAST_PYCCALL
      if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
        PyObject *__pyx_temp[2] = {__pyx_t_7, __pyx_t_6};
        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 54, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      } else
      #endif
      {
        __pyx_t_8 = PyTuple_New(1+1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 54, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_8);
        __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_7); __pyx_t_7 = NULL;
        __Pyx_GIVEREF(__pyx_t_6);
        PyTuple_SET_ITEM(__pyx_t_8, 0+1, __pyx_t_6);
        __pyx_t_6 = 0;
        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_8, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 54, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      }
    }
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_r = __pyx_t_4;
    __pyx_t_4 = 0;
    __pyx_cur_scope->__pyx_t_0 = __pyx_t_1;
    __pyx_cur_scope->__pyx_t_1 = __pyx_t_2;
    __pyx_cur_scope->__pyx_t_2 = __pyx_t_3;
    __Pyx_XGIVEREF(__pyx_r);
    __Pyx_RefNannyFinishContext();
    __Pyx_Coroutine_ResetAndClearException(__pyx_generator);
    /* return from generator, yielding value */
    __pyx_generator->resume_label = 1;
    return __pyx_r;
    __pyx_L6_resume_from_yield:;
    __pyx_t_1 = __pyx_cur_scope->__pyx_t_0;
    __pyx_t_2 = __pyx_cur_scope->__pyx_t_1;
    __pyx_t_3 = __pyx_cur_scope->__pyx_t_2;
    if (unlikely(!__pyx_sent_value)) __PYX_ERR(0, 54, __pyx_L1_error)
  }
  CYTHON_MAYBE_UNUSED_VAR(__pyx_cur_scope);

  /* function exit code */
  PyErr_SetNone(PyExc_StopIteration);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_AddTraceback("genexpr", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_r); __pyx_r = 0;
  __Pyx_Coroutine_ResetAndClearException(__pyx_generator);
  __pyx_generator->resume_label = -1;
  __Pyx_Coroutine_clear((PyObject*)__pyx_generator);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_2 = __Pyx_GetModuleGlobalName(__pyx_n_s_repr_ellipsized); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 54, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_csv); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 54, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __pyx_pf_4xpra_6server_6window_6motion_2dd_genexpr(((PyObject*)__pyx_cur_scope)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 54, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_6 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
    __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_4);
    if (likely(__pyx_t_6)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_6);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_4, function);
    }
  }
  if (!__pyx_t_6) {
    __pyx_t_3 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_5); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 54, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __Pyx_GOTREF(__pyx_t_3);
  } else {
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_4)) {
      PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
      __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 54, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
      PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_t_5};
      __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 54, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    } else
    #endif
    {
      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 54, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __pyx_t_6 = NULL;
      __Pyx_GIVEREF(__pyx_t_5);
      PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_5);
      __pyx_t_5 = 0;
      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_7, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 54, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    }
  }
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2);
    if (likely(__pyx_t_4)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_4);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_2, function);
    }
  }
  if (!__pyx_t_4) {
    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 54, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_GOTREF(__pyx_t_1);
  } else {
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_2)) {
      PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_3};
      __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 54, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
      PyObject *__pyx_temp[2] = {__pyx_t_4, __pyx_t_3};
      __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 54, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    } else
    #endif
    {
      __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 54, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_4); __pyx_t_4 = NULL;
      __Pyx_GIVEREF(__pyx_t_3);
      PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_t_3);
      __pyx_t_3 = 0;
      __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_7, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 54, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    }
  }
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;
/* … */
struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct_3_genexpr {
  PyObject_HEAD
  struct __pyx_obj_4xpra_6server_6window_6motion___pyx_scope_struct_2___pyx_f_4xpra_6server_6window_6motion_dd *__pyx_outer_scope;
  uint16_t __pyx_v_i;
  uint16_t __pyx_t_0;
  uint16_t __pyx_t_1;
  uint16_t __pyx_t_2;
};


 055: 
 056: 
+057: assert sizeof(uint64_t)==64//8, "uint64_t is not 64-bit: %i!" % sizeof(uint64_t)
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    if (unlikely(!(((sizeof(uint64_t)) == 8) != 0))) {
      __pyx_t_2 = __Pyx_PyInt_FromSize_t((sizeof(uint64_t))); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_1 = __Pyx_PyString_Format(__pyx_kp_s_uint64_t_is_not_64_bit_i, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 57, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      PyErr_SetObject(PyExc_AssertionError, __pyx_t_1);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __PYX_ERR(0, 57, __pyx_L1_error)
    }
  }
  #endif
 058: 
 059: 
+060: cdef class ScrollData:
struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData {
  PyObject_HEAD
  struct __pyx_vtabstruct_4xpra_6server_6window_6motion_ScrollData *__pyx_vtab;
  PyObject *__weakref__;
  uint16_t *distances;
  uint64_t *a1;
  uint64_t *a2;
  uint8_t matched;
  uint16_t x;
  uint16_t y;
  uint16_t width;
  uint16_t height;
};
/* … */
struct __pyx_vtabstruct_4xpra_6server_6window_6motion_ScrollData {
  PyObject *(*match_distance)(struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *, uint8_t *, int16_t);
};
static struct __pyx_vtabstruct_4xpra_6server_6window_6motion_ScrollData *__pyx_vtabptr_4xpra_6server_6window_6motion_ScrollData;
 061: 
 062:     cdef object __weakref__
 063:     #for each distance, keep track of the hit count:
 064:     cdef uint16_t *distances
 065:     cdef uint64_t *a1        #checksums of reference picture
 066:     cdef uint64_t *a2        #checksums of latest picture
 067:     cdef uint8_t matched
 068:     cdef uint16_t x
 069:     cdef uint16_t y
 070:     cdef uint16_t width
 071:     cdef uint16_t height
 072: 
+073:     def __cinit__(self, uint16_t x=0, uint16_t y=0, uint16_t width=0, uint16_t height=0):
/* Python wrapper */
static int __pyx_pw_4xpra_6server_6window_6motion_10ScrollData_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static int __pyx_pw_4xpra_6server_6window_6motion_10ScrollData_1__cinit__(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  uint16_t __pyx_v_x;
  uint16_t __pyx_v_y;
  uint16_t __pyx_v_width;
  uint16_t __pyx_v_height;
  int __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__cinit__ (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,&__pyx_n_s_y,&__pyx_n_s_width,&__pyx_n_s_height,0};
    PyObject* values[4] = {0,0,0,0};
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_x);
          if (value) { values[0] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  1:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_y);
          if (value) { values[1] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_width);
          if (value) { values[2] = value; kw_args--; }
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_height);
          if (value) { values[3] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "__cinit__") < 0)) __PYX_ERR(0, 73, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    if (values[0]) {
      __pyx_v_x = __Pyx_PyInt_As_uint16_t(values[0]); if (unlikely((__pyx_v_x == ((uint16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 73, __pyx_L3_error)
    } else {
      __pyx_v_x = ((uint16_t)0);
    }
    if (values[1]) {
      __pyx_v_y = __Pyx_PyInt_As_uint16_t(values[1]); if (unlikely((__pyx_v_y == ((uint16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 73, __pyx_L3_error)
    } else {
      __pyx_v_y = ((uint16_t)0);
    }
    if (values[2]) {
      __pyx_v_width = __Pyx_PyInt_As_uint16_t(values[2]); if (unlikely((__pyx_v_width == ((uint16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 73, __pyx_L3_error)
    } else {
      __pyx_v_width = ((uint16_t)0);
    }
    if (values[3]) {
      __pyx_v_height = __Pyx_PyInt_As_uint16_t(values[3]); if (unlikely((__pyx_v_height == ((uint16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 73, __pyx_L3_error)
    } else {
      __pyx_v_height = ((uint16_t)0);
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("__cinit__", 0, 0, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 73, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("xpra.server.window.motion.ScrollData.__cinit__", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return -1;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_4xpra_6server_6window_6motion_10ScrollData___cinit__(((struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *)__pyx_v_self), __pyx_v_x, __pyx_v_y, __pyx_v_width, __pyx_v_height);

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static int __pyx_pf_4xpra_6server_6window_6motion_10ScrollData___cinit__(struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *__pyx_v_self, uint16_t __pyx_v_x, uint16_t __pyx_v_y, uint16_t __pyx_v_width, uint16_t __pyx_v_height) {
  int __pyx_r;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__cinit__", 0);
/* … */
  /* function exit code */
  __pyx_r = 0;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
+074:         self.x = x
  __pyx_v_self->x = __pyx_v_x;
+075:         self.y = y
  __pyx_v_self->y = __pyx_v_y;
+076:         self.width = width
  __pyx_v_self->width = __pyx_v_width;
+077:         self.height = height
  __pyx_v_self->height = __pyx_v_height;
 078: 
+079:     def __repr__(self):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_3__repr__(PyObject *__pyx_v_self); /*proto*/
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_3__repr__(PyObject *__pyx_v_self) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__repr__ (wrapper)", 0);
  __pyx_r = __pyx_pf_4xpra_6server_6window_6motion_10ScrollData_2__repr__(((struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *)__pyx_v_self));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_6window_6motion_10ScrollData_2__repr__(struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *__pyx_v_self) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__repr__", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_AddTraceback("xpra.server.window.motion.ScrollData.__repr__", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
+080:         return "ScrollDistances(%ix%i)" % (self.width, self.height)
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_1 = __Pyx_PyInt_From_uint16_t(__pyx_v_self->width); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 80, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyInt_From_uint16_t(__pyx_v_self->height); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 80, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 80, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_2);
  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
  __pyx_t_1 = 0;
  __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyString_Format(__pyx_kp_s_ScrollDistances_ix_i, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 80, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_r = __pyx_t_2;
  __pyx_t_2 = 0;
  goto __pyx_L0;
 081: 
 082:     #only used by the unit tests:
+083:     def _test_update(self, arr):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_5_test_update(PyObject *__pyx_v_self, PyObject *__pyx_v_arr); /*proto*/
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_5_test_update(PyObject *__pyx_v_self, PyObject *__pyx_v_arr) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_test_update (wrapper)", 0);
  __pyx_r = __pyx_pf_4xpra_6server_6window_6motion_10ScrollData_4_test_update(((struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *)__pyx_v_self), ((PyObject *)__pyx_v_arr));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_6window_6motion_10ScrollData_4_test_update(struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *__pyx_v_self, PyObject *__pyx_v_arr) {
  uint16_t __pyx_v_l;
  size_t __pyx_v_asize;
  PyObject *__pyx_v_i = NULL;
  PyObject *__pyx_v_v = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_test_update", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_AddTraceback("xpra.server.window.motion.ScrollData._test_update", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_i);
  __Pyx_XDECREF(__pyx_v_v);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
+084:         if self.a1:
  __pyx_t_1 = (__pyx_v_self->a1 != 0);
  if (__pyx_t_1) {
/* … */
  }
+085:             free(self.a1)
    free(__pyx_v_self->a1);
+086:             self.a1 = NULL
    __pyx_v_self->a1 = NULL;
+087:         if self.a2:
  __pyx_t_1 = (__pyx_v_self->a2 != 0);
  if (__pyx_t_1) {
/* … */
  }
+088:             self.a1 = self.a2
    __pyx_t_2 = __pyx_v_self->a2;
    __pyx_v_self->a1 = __pyx_t_2;
+089:             self.a2 = NULL
    __pyx_v_self->a2 = NULL;
+090:         cdef uint16_t l = len(arr)
  __pyx_t_3 = PyObject_Length(__pyx_v_arr); if (unlikely(__pyx_t_3 == ((Py_ssize_t)-1))) __PYX_ERR(0, 90, __pyx_L1_error)
  __pyx_v_l = __pyx_t_3;
+091:         cdef size_t asize = l*(sizeof(uint64_t))
  __pyx_v_asize = (__pyx_v_l * (sizeof(uint64_t)));
+092:         self.a2 = <uint64_t*> memalign(asize)
  __pyx_v_self->a2 = ((uint64_t *)__pyx_f_4xpra_7buffers_6membuf_memalign(__pyx_v_asize));
+093:         assert self.a2!=NULL, "checksum memory allocation failed"
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    if (unlikely(!((__pyx_v_self->a2 != NULL) != 0))) {
      PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_checksum_memory_allocation_faile);
      __PYX_ERR(0, 93, __pyx_L1_error)
    }
  }
  #endif
+094:         for i,v in enumerate(arr):
  __Pyx_INCREF(__pyx_int_0);
  __pyx_t_4 = __pyx_int_0;
  if (likely(PyList_CheckExact(__pyx_v_arr)) || PyTuple_CheckExact(__pyx_v_arr)) {
    __pyx_t_5 = __pyx_v_arr; __Pyx_INCREF(__pyx_t_5); __pyx_t_3 = 0;
    __pyx_t_6 = NULL;
  } else {
    __pyx_t_3 = -1; __pyx_t_5 = PyObject_GetIter(__pyx_v_arr); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 94, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_6 = Py_TYPE(__pyx_t_5)->tp_iternext; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 94, __pyx_L1_error)
  }
  for (;;) {
    if (likely(!__pyx_t_6)) {
      if (likely(PyList_CheckExact(__pyx_t_5))) {
        if (__pyx_t_3 >= PyList_GET_SIZE(__pyx_t_5)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_7 = PyList_GET_ITEM(__pyx_t_5, __pyx_t_3); __Pyx_INCREF(__pyx_t_7); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 94, __pyx_L1_error)
        #else
        __pyx_t_7 = PySequence_ITEM(__pyx_t_5, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 94, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        #endif
      } else {
        if (__pyx_t_3 >= PyTuple_GET_SIZE(__pyx_t_5)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_7 = PyTuple_GET_ITEM(__pyx_t_5, __pyx_t_3); __Pyx_INCREF(__pyx_t_7); __pyx_t_3++; if (unlikely(0 < 0)) __PYX_ERR(0, 94, __pyx_L1_error)
        #else
        __pyx_t_7 = PySequence_ITEM(__pyx_t_5, __pyx_t_3); __pyx_t_3++; if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 94, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        #endif
      }
    } else {
      __pyx_t_7 = __pyx_t_6(__pyx_t_5);
      if (unlikely(!__pyx_t_7)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 94, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_7);
    }
    __Pyx_XDECREF_SET(__pyx_v_v, __pyx_t_7);
    __pyx_t_7 = 0;
    __Pyx_INCREF(__pyx_t_4);
    __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_4);
    __pyx_t_7 = __Pyx_PyInt_AddObjC(__pyx_t_4, __pyx_int_1, 1, 0); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 94, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __Pyx_DECREF(__pyx_t_4);
    __pyx_t_4 = __pyx_t_7;
    __pyx_t_7 = 0;
/* … */
  }
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+095:             self.a2[i] = <uint64_t> abs(v)
    __pyx_t_7 = __Pyx_PyNumber_Absolute(__pyx_v_v); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 95, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __pyx_t_8 = __Pyx_PyInt_As_uint64_t(__pyx_t_7); if (unlikely((__pyx_t_8 == ((uint64_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 95, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    __pyx_t_9 = __Pyx_PyIndex_AsSsize_t(__pyx_v_i); if (unlikely((__pyx_t_9 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 95, __pyx_L1_error)
    (__pyx_v_self->a2[__pyx_t_9]) = ((uint64_t)__pyx_t_8);
 096: 
+097:     def update(self, pixels, uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t rowstride, uint8_t bpp=4):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_7update(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_4xpra_6server_6window_6motion_10ScrollData_6update[] = "\n            Add a new image to compare with,\n            checksum its rows into a2,\n            and push existing values (if we had any) into a1.\n        ";
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_7update(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_pixels = 0;
  uint16_t __pyx_v_x;
  uint16_t __pyx_v_y;
  uint16_t __pyx_v_width;
  uint16_t __pyx_v_height;
  uint16_t __pyx_v_rowstride;
  uint8_t __pyx_v_bpp;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("update (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_pixels,&__pyx_n_s_x,&__pyx_n_s_y,&__pyx_n_s_width,&__pyx_n_s_height,&__pyx_n_s_rowstride,&__pyx_n_s_bpp,0};
    PyObject* values[7] = {0,0,0,0,0,0,0};
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
        CYTHON_FALLTHROUGH;
        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
        CYTHON_FALLTHROUGH;
        case  5: values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        CYTHON_FALLTHROUGH;
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_pixels)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("update", 0, 6, 7, 1); __PYX_ERR(0, 97, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_y)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("update", 0, 6, 7, 2); __PYX_ERR(0, 97, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_width)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("update", 0, 6, 7, 3); __PYX_ERR(0, 97, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  4:
        if (likely((values[4] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_height)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("update", 0, 6, 7, 4); __PYX_ERR(0, 97, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  5:
        if (likely((values[5] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_rowstride)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("update", 0, 6, 7, 5); __PYX_ERR(0, 97, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  6:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_bpp);
          if (value) { values[6] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "update") < 0)) __PYX_ERR(0, 97, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  7: values[6] = PyTuple_GET_ITEM(__pyx_args, 6);
        CYTHON_FALLTHROUGH;
        case  6: values[5] = PyTuple_GET_ITEM(__pyx_args, 5);
        values[4] = PyTuple_GET_ITEM(__pyx_args, 4);
        values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    __pyx_v_pixels = values[0];
    __pyx_v_x = __Pyx_PyInt_As_uint16_t(values[1]); if (unlikely((__pyx_v_x == ((uint16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 97, __pyx_L3_error)
    __pyx_v_y = __Pyx_PyInt_As_uint16_t(values[2]); if (unlikely((__pyx_v_y == ((uint16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 97, __pyx_L3_error)
    __pyx_v_width = __Pyx_PyInt_As_uint16_t(values[3]); if (unlikely((__pyx_v_width == ((uint16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 97, __pyx_L3_error)
    __pyx_v_height = __Pyx_PyInt_As_uint16_t(values[4]); if (unlikely((__pyx_v_height == ((uint16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 97, __pyx_L3_error)
    __pyx_v_rowstride = __Pyx_PyInt_As_uint16_t(values[5]); if (unlikely((__pyx_v_rowstride == ((uint16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 97, __pyx_L3_error)
    if (values[6]) {
      __pyx_v_bpp = __Pyx_PyInt_As_uint8_t(values[6]); if (unlikely((__pyx_v_bpp == ((uint8_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 97, __pyx_L3_error)
    } else {
      __pyx_v_bpp = ((uint8_t)4);
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("update", 0, 6, 7, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 97, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("xpra.server.window.motion.ScrollData.update", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_4xpra_6server_6window_6motion_10ScrollData_6update(((struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *)__pyx_v_self), __pyx_v_pixels, __pyx_v_x, __pyx_v_y, __pyx_v_width, __pyx_v_height, __pyx_v_rowstride, __pyx_v_bpp);

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_6window_6motion_10ScrollData_6update(struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *__pyx_v_self, PyObject *__pyx_v_pixels, uint16_t __pyx_v_x, uint16_t __pyx_v_y, uint16_t __pyx_v_width, uint16_t __pyx_v_height, uint16_t __pyx_v_rowstride, uint8_t __pyx_v_bpp) {
  size_t __pyx_v_asize;
  uint8_t *__pyx_v_buf;
  Py_ssize_t __pyx_v_buf_len;
  Py_ssize_t __pyx_v_min_buf_len;
  size_t __pyx_v_row_len;
  uint64_t *__pyx_v_a2;
  unsigned PY_LONG_LONG __pyx_v_seed;
  uint16_t __pyx_v_i;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("update", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_XDECREF(__pyx_t_9);
  __Pyx_XDECREF(__pyx_t_10);
  __Pyx_XDECREF(__pyx_t_11);
  __Pyx_AddTraceback("xpra.server.window.motion.ScrollData.update", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 098:         """
 099:             Add a new image to compare with,
 100:             checksum its rows into a2,
 101:             and push existing values (if we had any) into a1.
 102:         """
+103:         if DEBUG:
  __pyx_t_1 = (__pyx_v_4xpra_6server_6window_6motion_DEBUG != 0);
  if (__pyx_t_1) {
/* … */
  }
+104:             log("%s.update%s a1=%#x, a2=%#x, distances=%#x, current size: %ix%i", self, (repr_ellipsized(pixels), x, y, width, height, rowstride, bpp), <uintptr_t> self.a1, <uintptr_t> self.a2, <uintptr_t> self.distances, self.width, self.height)
    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_log); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_repr_ellipsized); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_6 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_5);
      if (likely(__pyx_t_6)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_6);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_5, function);
      }
    }
    if (!__pyx_t_6) {
      __pyx_t_4 = __Pyx_PyObject_CallOneArg(__pyx_t_5, __pyx_v_pixels); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 104, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
    } else {
      #if CYTHON_FAST_PYCALL
      if (PyFunction_Check(__pyx_t_5)) {
        PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v_pixels};
        __pyx_t_4 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 104, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
        __Pyx_GOTREF(__pyx_t_4);
      } else
      #endif
      #if CYTHON_FAST_PYCCALL
      if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
        PyObject *__pyx_temp[2] = {__pyx_t_6, __pyx_v_pixels};
        __pyx_t_4 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-1, 1+1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 104, __pyx_L1_error)
        __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
        __Pyx_GOTREF(__pyx_t_4);
      } else
      #endif
      {
        __pyx_t_7 = PyTuple_New(1+1); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 104, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_7);
        __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_6); __pyx_t_6 = NULL;
        __Pyx_INCREF(__pyx_v_pixels);
        __Pyx_GIVEREF(__pyx_v_pixels);
        PyTuple_SET_ITEM(__pyx_t_7, 0+1, __pyx_v_pixels);
        __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_7, NULL); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 104, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      }
    }
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_t_5 = __Pyx_PyInt_From_uint16_t(__pyx_v_x); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_7 = __Pyx_PyInt_From_uint16_t(__pyx_v_y); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __pyx_t_6 = __Pyx_PyInt_From_uint16_t(__pyx_v_width); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_8 = __Pyx_PyInt_From_uint16_t(__pyx_v_height); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __pyx_t_9 = __Pyx_PyInt_From_uint16_t(__pyx_v_rowstride); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_9);
    __pyx_t_10 = __Pyx_PyInt_From_uint8_t(__pyx_v_bpp); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_10);
    __pyx_t_11 = PyTuple_New(7); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_11);
    __Pyx_GIVEREF(__pyx_t_4);
    PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_t_4);
    __Pyx_GIVEREF(__pyx_t_5);
    PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_t_5);
    __Pyx_GIVEREF(__pyx_t_7);
    PyTuple_SET_ITEM(__pyx_t_11, 2, __pyx_t_7);
    __Pyx_GIVEREF(__pyx_t_6);
    PyTuple_SET_ITEM(__pyx_t_11, 3, __pyx_t_6);
    __Pyx_GIVEREF(__pyx_t_8);
    PyTuple_SET_ITEM(__pyx_t_11, 4, __pyx_t_8);
    __Pyx_GIVEREF(__pyx_t_9);
    PyTuple_SET_ITEM(__pyx_t_11, 5, __pyx_t_9);
    __Pyx_GIVEREF(__pyx_t_10);
    PyTuple_SET_ITEM(__pyx_t_11, 6, __pyx_t_10);
    __pyx_t_4 = 0;
    __pyx_t_5 = 0;
    __pyx_t_7 = 0;
    __pyx_t_6 = 0;
    __pyx_t_8 = 0;
    __pyx_t_9 = 0;
    __pyx_t_10 = 0;
    __pyx_t_10 = __Pyx_PyInt_FromSize_t(((uintptr_t)__pyx_v_self->a1)); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_10);
    __pyx_t_9 = __Pyx_PyInt_FromSize_t(((uintptr_t)__pyx_v_self->a2)); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_9);
    __pyx_t_8 = __Pyx_PyInt_FromSize_t(((uintptr_t)__pyx_v_self->distances)); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __pyx_t_6 = __Pyx_PyInt_From_uint16_t(__pyx_v_self->width); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_7 = __Pyx_PyInt_From_uint16_t(__pyx_v_self->height); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __pyx_t_5 = NULL;
    __pyx_t_12 = 0;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
      if (likely(__pyx_t_5)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
        __Pyx_INCREF(__pyx_t_5);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_3, function);
        __pyx_t_12 = 1;
      }
    }
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[9] = {__pyx_t_5, __pyx_kp_s_s_update_s_a1_x_a2_x_distances, ((PyObject *)__pyx_v_self), __pyx_t_11, __pyx_t_10, __pyx_t_9, __pyx_t_8, __pyx_t_6, __pyx_t_7};
      __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_12, 8+__pyx_t_12); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 104, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[9] = {__pyx_t_5, __pyx_kp_s_s_update_s_a1_x_a2_x_distances, ((PyObject *)__pyx_v_self), __pyx_t_11, __pyx_t_10, __pyx_t_9, __pyx_t_8, __pyx_t_6, __pyx_t_7};
      __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_12, 8+__pyx_t_12); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 104, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    } else
    #endif
    {
      __pyx_t_4 = PyTuple_New(8+__pyx_t_12); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 104, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      if (__pyx_t_5) {
        __Pyx_GIVEREF(__pyx_t_5); PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_5); __pyx_t_5 = NULL;
      }
      __Pyx_INCREF(__pyx_kp_s_s_update_s_a1_x_a2_x_distances);
      __Pyx_GIVEREF(__pyx_kp_s_s_update_s_a1_x_a2_x_distances);
      PyTuple_SET_ITEM(__pyx_t_4, 0+__pyx_t_12, __pyx_kp_s_s_update_s_a1_x_a2_x_distances);
      __Pyx_INCREF(((PyObject *)__pyx_v_self));
      __Pyx_GIVEREF(((PyObject *)__pyx_v_self));
      PyTuple_SET_ITEM(__pyx_t_4, 1+__pyx_t_12, ((PyObject *)__pyx_v_self));
      __Pyx_GIVEREF(__pyx_t_11);
      PyTuple_SET_ITEM(__pyx_t_4, 2+__pyx_t_12, __pyx_t_11);
      __Pyx_GIVEREF(__pyx_t_10);
      PyTuple_SET_ITEM(__pyx_t_4, 3+__pyx_t_12, __pyx_t_10);
      __Pyx_GIVEREF(__pyx_t_9);
      PyTuple_SET_ITEM(__pyx_t_4, 4+__pyx_t_12, __pyx_t_9);
      __Pyx_GIVEREF(__pyx_t_8);
      PyTuple_SET_ITEM(__pyx_t_4, 5+__pyx_t_12, __pyx_t_8);
      __Pyx_GIVEREF(__pyx_t_6);
      PyTuple_SET_ITEM(__pyx_t_4, 6+__pyx_t_12, __pyx_t_6);
      __Pyx_GIVEREF(__pyx_t_7);
      PyTuple_SET_ITEM(__pyx_t_4, 7+__pyx_t_12, __pyx_t_7);
      __pyx_t_11 = 0;
      __pyx_t_10 = 0;
      __pyx_t_9 = 0;
      __pyx_t_8 = 0;
      __pyx_t_6 = 0;
      __pyx_t_7 = 0;
      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 104, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    }
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+105:         assert width>0 and height>0, "invalid dimensions: %ix%i" % (width, height)
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    __pyx_t_13 = ((__pyx_v_width > 0) != 0);
    if (__pyx_t_13) {
    } else {
      __pyx_t_1 = __pyx_t_13;
      goto __pyx_L4_bool_binop_done;
    }
    __pyx_t_13 = ((__pyx_v_height > 0) != 0);
    __pyx_t_1 = __pyx_t_13;
    __pyx_L4_bool_binop_done:;
    if (unlikely(!__pyx_t_1)) {
      __pyx_t_2 = __Pyx_PyInt_From_uint16_t(__pyx_v_width); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 105, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_3 = __Pyx_PyInt_From_uint16_t(__pyx_v_height); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 105, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_4 = PyTuple_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 105, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __Pyx_GIVEREF(__pyx_t_2);
      PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_2);
      __Pyx_GIVEREF(__pyx_t_3);
      PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_3);
      __pyx_t_2 = 0;
      __pyx_t_3 = 0;
      __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_invalid_dimensions_ix_i, __pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 105, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      PyErr_SetObject(PyExc_AssertionError, __pyx_t_3);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __PYX_ERR(0, 105, __pyx_L1_error)
    }
  }
  #endif
 106:         #this is a new picture, shift a2 into a1 if we have it:
+107:         if self.a1:
  __pyx_t_1 = (__pyx_v_self->a1 != 0);
  if (__pyx_t_1) {
/* … */
  }
+108:             free(self.a1)
    free(__pyx_v_self->a1);
+109:             self.a1 = NULL
    __pyx_v_self->a1 = NULL;
+110:         if self.a2:
  __pyx_t_1 = (__pyx_v_self->a2 != 0);
  if (__pyx_t_1) {
/* … */
  }
+111:             self.a1 = self.a2
    __pyx_t_14 = __pyx_v_self->a2;
    __pyx_v_self->a1 = __pyx_t_14;
+112:             self.a2 = NULL
    __pyx_v_self->a2 = NULL;
 113:         #scroll area can move within the window:
+114:         self.x = x
  __pyx_v_self->x = __pyx_v_x;
+115:         self.y = y
  __pyx_v_self->y = __pyx_v_y;
 116:         #but cannot change size (checksums would not match):
+117:         if height!=self.height or width!=self.width:
  __pyx_t_13 = ((__pyx_v_height != __pyx_v_self->height) != 0);
  if (!__pyx_t_13) {
  } else {
    __pyx_t_1 = __pyx_t_13;
    goto __pyx_L9_bool_binop_done;
  }
  __pyx_t_13 = ((__pyx_v_width != __pyx_v_self->width) != 0);
  __pyx_t_1 = __pyx_t_13;
  __pyx_L9_bool_binop_done:;
  if (__pyx_t_1) {
/* … */
  }
+118:             log("new image size: %ix%i (was %ix%i), clearing reference checksums", width, height, self.width, self.height)
    __pyx_t_4 = __Pyx_GetModuleGlobalName(__pyx_n_s_log); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 118, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_2 = __Pyx_PyInt_From_uint16_t(__pyx_v_width); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 118, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_7 = __Pyx_PyInt_From_uint16_t(__pyx_v_height); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 118, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __pyx_t_6 = __Pyx_PyInt_From_uint16_t(__pyx_v_self->width); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 118, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_8 = __Pyx_PyInt_From_uint16_t(__pyx_v_self->height); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 118, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __pyx_t_9 = NULL;
    __pyx_t_12 = 0;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
      __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_4);
      if (likely(__pyx_t_9)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
        __Pyx_INCREF(__pyx_t_9);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_4, function);
        __pyx_t_12 = 1;
      }
    }
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_4)) {
      PyObject *__pyx_temp[6] = {__pyx_t_9, __pyx_kp_s_new_image_size_ix_i_was_ix_i_cle, __pyx_t_2, __pyx_t_7, __pyx_t_6, __pyx_t_8};
      __pyx_t_3 = __Pyx_PyFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_12, 5+__pyx_t_12); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 118, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_4)) {
      PyObject *__pyx_temp[6] = {__pyx_t_9, __pyx_kp_s_new_image_size_ix_i_was_ix_i_cle, __pyx_t_2, __pyx_t_7, __pyx_t_6, __pyx_t_8};
      __pyx_t_3 = __Pyx_PyCFunction_FastCall(__pyx_t_4, __pyx_temp+1-__pyx_t_12, 5+__pyx_t_12); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 118, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    } else
    #endif
    {
      __pyx_t_10 = PyTuple_New(5+__pyx_t_12); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 118, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      if (__pyx_t_9) {
        __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_9); __pyx_t_9 = NULL;
      }
      __Pyx_INCREF(__pyx_kp_s_new_image_size_ix_i_was_ix_i_cle);
      __Pyx_GIVEREF(__pyx_kp_s_new_image_size_ix_i_was_ix_i_cle);
      PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_12, __pyx_kp_s_new_image_size_ix_i_was_ix_i_cle);
      __Pyx_GIVEREF(__pyx_t_2);
      PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_12, __pyx_t_2);
      __Pyx_GIVEREF(__pyx_t_7);
      PyTuple_SET_ITEM(__pyx_t_10, 2+__pyx_t_12, __pyx_t_7);
      __Pyx_GIVEREF(__pyx_t_6);
      PyTuple_SET_ITEM(__pyx_t_10, 3+__pyx_t_12, __pyx_t_6);
      __Pyx_GIVEREF(__pyx_t_8);
      PyTuple_SET_ITEM(__pyx_t_10, 4+__pyx_t_12, __pyx_t_8);
      __pyx_t_2 = 0;
      __pyx_t_7 = 0;
      __pyx_t_6 = 0;
      __pyx_t_8 = 0;
      __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_4, __pyx_t_10, NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 118, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
    }
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+119:             if self.a1:
    __pyx_t_1 = (__pyx_v_self->a1 != 0);
    if (__pyx_t_1) {
/* … */
    }
+120:                 free(self.a1)
      free(__pyx_v_self->a1);
+121:                 self.a1 = NULL
      __pyx_v_self->a1 = NULL;
+122:             if self.distances:
    __pyx_t_1 = (__pyx_v_self->distances != 0);
    if (__pyx_t_1) {
/* … */
    }
+123:                 free(self.distances)
      free(__pyx_v_self->distances);
+124:                 self.distances = NULL
      __pyx_v_self->distances = NULL;
+125:             self.width = width
    __pyx_v_self->width = __pyx_v_width;
+126:             self.height = height
    __pyx_v_self->height = __pyx_v_height;
 127:         #allocate new checksum array:
+128:         assert self.a2==NULL
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    if (unlikely(!((__pyx_v_self->a2 == NULL) != 0))) {
      PyErr_SetNone(PyExc_AssertionError);
      __PYX_ERR(0, 128, __pyx_L1_error)
    }
  }
  #endif
+129:         cdef size_t asize = height*(sizeof(uint64_t))
  __pyx_v_asize = (__pyx_v_height * (sizeof(uint64_t)));
+130:         self.a2 = <uint64_t*> memalign(asize)
  __pyx_v_self->a2 = ((uint64_t *)__pyx_f_4xpra_7buffers_6membuf_memalign(__pyx_v_asize));
+131:         assert self.a2!=NULL, "checksum memory allocation failed"
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    if (unlikely(!((__pyx_v_self->a2 != NULL) != 0))) {
      PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_checksum_memory_allocation_faile);
      __PYX_ERR(0, 131, __pyx_L1_error)
    }
  }
  #endif
 132:         #checksum each line of the pixel array:
+133:         cdef uint8_t *buf = NULL
  __pyx_v_buf = NULL;
+134:         cdef Py_ssize_t buf_len = 0
  __pyx_v_buf_len = 0;
+135:         cdef Py_ssize_t min_buf_len = rowstride*height
  __pyx_v_min_buf_len = (__pyx_v_rowstride * __pyx_v_height);
+136:         assert object_as_buffer(pixels, <const void**> &buf, &buf_len)==0
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    if (unlikely(!((__pyx_f_4xpra_7buffers_6membuf_object_as_buffer(__pyx_v_pixels, ((void const **)(&__pyx_v_buf)), (&__pyx_v_buf_len)) == 0) != 0))) {
      PyErr_SetNone(PyExc_AssertionError);
      __PYX_ERR(0, 136, __pyx_L1_error)
    }
  }
  #endif
+137:         assert buf_len>=0 and buf_len>=min_buf_len, "buffer length=%i is too small for %ix%i" % (buf_len, rowstride, height)
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    __pyx_t_13 = ((__pyx_v_buf_len >= 0) != 0);
    if (__pyx_t_13) {
    } else {
      __pyx_t_1 = __pyx_t_13;
      goto __pyx_L13_bool_binop_done;
    }
    __pyx_t_13 = ((__pyx_v_buf_len >= __pyx_v_min_buf_len) != 0);
    __pyx_t_1 = __pyx_t_13;
    __pyx_L13_bool_binop_done:;
    if (unlikely(!__pyx_t_1)) {
      __pyx_t_3 = PyInt_FromSsize_t(__pyx_v_buf_len); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 137, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_4 = __Pyx_PyInt_From_uint16_t(__pyx_v_rowstride); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 137, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_10 = __Pyx_PyInt_From_uint16_t(__pyx_v_height); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 137, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      __pyx_t_8 = PyTuple_New(3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 137, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __Pyx_GIVEREF(__pyx_t_3);
      PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_3);
      __Pyx_GIVEREF(__pyx_t_4);
      PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_4);
      __Pyx_GIVEREF(__pyx_t_10);
      PyTuple_SET_ITEM(__pyx_t_8, 2, __pyx_t_10);
      __pyx_t_3 = 0;
      __pyx_t_4 = 0;
      __pyx_t_10 = 0;
      __pyx_t_10 = __Pyx_PyString_Format(__pyx_kp_s_buffer_length_i_is_too_small_for, __pyx_t_8); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 137, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
      PyErr_SetObject(PyExc_AssertionError, __pyx_t_10);
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      __PYX_ERR(0, 137, __pyx_L1_error)
    }
  }
  #endif
+138:         cdef size_t row_len = width*bpp
  __pyx_v_row_len = (__pyx_v_width * __pyx_v_bpp);
+139:         assert row_len<=rowstride, "invalid row length: %ix%i=%i but rowstride is %i" % (width, bpp, width*bpp, rowstride)
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    if (unlikely(!((__pyx_v_row_len <= __pyx_v_rowstride) != 0))) {
      __pyx_t_10 = __Pyx_PyInt_From_uint16_t(__pyx_v_width); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 139, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      __pyx_t_8 = __Pyx_PyInt_From_uint8_t(__pyx_v_bpp); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 139, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_8);
      __pyx_t_4 = __Pyx_PyInt_From_int((__pyx_v_width * __pyx_v_bpp)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 139, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_3 = __Pyx_PyInt_From_uint16_t(__pyx_v_rowstride); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 139, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_6 = PyTuple_New(4); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 139, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_GIVEREF(__pyx_t_10);
      PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_10);
      __Pyx_GIVEREF(__pyx_t_8);
      PyTuple_SET_ITEM(__pyx_t_6, 1, __pyx_t_8);
      __Pyx_GIVEREF(__pyx_t_4);
      PyTuple_SET_ITEM(__pyx_t_6, 2, __pyx_t_4);
      __Pyx_GIVEREF(__pyx_t_3);
      PyTuple_SET_ITEM(__pyx_t_6, 3, __pyx_t_3);
      __pyx_t_10 = 0;
      __pyx_t_8 = 0;
      __pyx_t_4 = 0;
      __pyx_t_3 = 0;
      __pyx_t_3 = __Pyx_PyString_Format(__pyx_kp_s_invalid_row_length_ix_i_i_but_ro, __pyx_t_6); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 139, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      PyErr_SetObject(PyExc_AssertionError, __pyx_t_3);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      __PYX_ERR(0, 139, __pyx_L1_error)
    }
  }
  #endif
+140:         cdef uint64_t *a2 = self.a2
  __pyx_t_14 = __pyx_v_self->a2;
  __pyx_v_a2 = __pyx_t_14;
+141:         cdef unsigned long long seed = 0
  __pyx_v_seed = 0;
 142:         cdef uint16_t i
+143:         with nogil:
  {
      #ifdef WITH_THREAD
      PyThreadState *_save;
      Py_UNBLOCK_THREADS
      __Pyx_FastGIL_Remember();
      #endif
      /*try:*/ {
/* … */
      /*finally:*/ {
        /*normal exit:*/{
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L17;
        }
        __pyx_L17:;
      }
  }
+144:             for i in range(height):
        __pyx_t_15 = __pyx_v_height;
        __pyx_t_16 = __pyx_t_15;
        for (__pyx_t_17 = 0; __pyx_t_17 < __pyx_t_16; __pyx_t_17+=1) {
          __pyx_v_i = __pyx_t_17;
+145:                 a2[i] = <uint64_t> xxh64(buf, row_len, seed)
          (__pyx_v_a2[__pyx_v_i]) = ((uint64_t)__pyx_f_4xpra_7buffers_6membuf_xxh64(__pyx_v_buf, __pyx_v_row_len, __pyx_v_seed));
 146:                 #import xxhash
 147:                 #a2[i] = <uint64_t> abs(xxhash.xxh64(buf[:row_len]).intdigest())
+148:                 buf += rowstride
          __pyx_v_buf = (__pyx_v_buf + __pyx_v_rowstride);
        }
      }
 149: 
+150:     def calculate(self, uint16_t max_distance=1000):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_9calculate(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_4xpra_6server_6window_6motion_10ScrollData_8calculate[] = "\n            Find all the scroll distances\n            that would move lines from a1 to a2.\n            The same lines may be accounted for multiple times.\n            The result is stored in the \"distances\" array.\n        ";
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_9calculate(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  uint16_t __pyx_v_max_distance;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("calculate (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_max_distance,0};
    PyObject* values[1] = {0};
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_max_distance);
          if (value) { values[0] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "calculate") < 0)) __PYX_ERR(0, 150, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    if (values[0]) {
      __pyx_v_max_distance = __Pyx_PyInt_As_uint16_t(values[0]); if (unlikely((__pyx_v_max_distance == ((uint16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 150, __pyx_L3_error)
    } else {
      __pyx_v_max_distance = ((uint16_t)0x3E8);
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("calculate", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 150, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("xpra.server.window.motion.ScrollData.calculate", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_4xpra_6server_6window_6motion_10ScrollData_8calculate(((struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *)__pyx_v_self), __pyx_v_max_distance);

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_6window_6motion_10ScrollData_8calculate(struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *__pyx_v_self, uint16_t __pyx_v_max_distance) {
  uint64_t *__pyx_v_a1;
  uint64_t *__pyx_v_a2;
  uint16_t __pyx_v_l;
  uint16_t __pyx_v_y1;
  uint16_t __pyx_v_y2;
  uint16_t __pyx_v_miny;
  uint16_t __pyx_v_maxy;
  uint64_t __pyx_v_a2v;
  uint16_t __pyx_v_matches;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("calculate", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_XDECREF(__pyx_t_10);
  __Pyx_AddTraceback("xpra.server.window.motion.ScrollData.calculate", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 151:         """
 152:             Find all the scroll distances
 153:             that would move lines from a1 to a2.
 154:             The same lines may be accounted for multiple times.
 155:             The result is stored in the "distances" array.
 156:         """
+157:         if DEBUG:
  __pyx_t_1 = (__pyx_v_4xpra_6server_6window_6motion_DEBUG != 0);
  if (__pyx_t_1) {
/* … */
  }
+158:             log("calculate(%i) a1=%#x, a2=%#x, distances=%#x", max_distance, <uintptr_t> self.a1, <uintptr_t> self.a2, <uintptr_t> self.distances)
    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_log); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 158, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_4 = __Pyx_PyInt_From_uint16_t(__pyx_v_max_distance); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 158, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_5 = __Pyx_PyInt_FromSize_t(((uintptr_t)__pyx_v_self->a1)); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 158, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_6 = __Pyx_PyInt_FromSize_t(((uintptr_t)__pyx_v_self->a2)); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 158, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_7 = __Pyx_PyInt_FromSize_t(((uintptr_t)__pyx_v_self->distances)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 158, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __pyx_t_8 = NULL;
    __pyx_t_9 = 0;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
      __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_3);
      if (likely(__pyx_t_8)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
        __Pyx_INCREF(__pyx_t_8);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_3, function);
        __pyx_t_9 = 1;
      }
    }
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[6] = {__pyx_t_8, __pyx_kp_s_calculate_i_a1_x_a2_x_distances, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7};
      __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 5+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 158, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[6] = {__pyx_t_8, __pyx_kp_s_calculate_i_a1_x_a2_x_distances, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7};
      __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 5+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 158, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    } else
    #endif
    {
      __pyx_t_10 = PyTuple_New(5+__pyx_t_9); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 158, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      if (__pyx_t_8) {
        __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_8); __pyx_t_8 = NULL;
      }
      __Pyx_INCREF(__pyx_kp_s_calculate_i_a1_x_a2_x_distances);
      __Pyx_GIVEREF(__pyx_kp_s_calculate_i_a1_x_a2_x_distances);
      PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, __pyx_kp_s_calculate_i_a1_x_a2_x_distances);
      __Pyx_GIVEREF(__pyx_t_4);
      PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_t_4);
      __Pyx_GIVEREF(__pyx_t_5);
      PyTuple_SET_ITEM(__pyx_t_10, 2+__pyx_t_9, __pyx_t_5);
      __Pyx_GIVEREF(__pyx_t_6);
      PyTuple_SET_ITEM(__pyx_t_10, 3+__pyx_t_9, __pyx_t_6);
      __Pyx_GIVEREF(__pyx_t_7);
      PyTuple_SET_ITEM(__pyx_t_10, 4+__pyx_t_9, __pyx_t_7);
      __pyx_t_4 = 0;
      __pyx_t_5 = 0;
      __pyx_t_6 = 0;
      __pyx_t_7 = 0;
      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_10, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 158, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
    }
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+159:         if self.a1==NULL or self.a2==NULL:
  __pyx_t_11 = ((__pyx_v_self->a1 == NULL) != 0);
  if (!__pyx_t_11) {
  } else {
    __pyx_t_1 = __pyx_t_11;
    goto __pyx_L5_bool_binop_done;
  }
  __pyx_t_11 = ((__pyx_v_self->a2 == NULL) != 0);
  __pyx_t_1 = __pyx_t_11;
  __pyx_L5_bool_binop_done:;
  if (__pyx_t_1) {
/* … */
  }
+160:             return
    __Pyx_XDECREF(__pyx_r);
    __pyx_r = Py_None; __Pyx_INCREF(Py_None);
    goto __pyx_L0;
+161:         cdef uint64_t *a1 = self.a1
  __pyx_t_12 = __pyx_v_self->a1;
  __pyx_v_a1 = __pyx_t_12;
+162:         cdef uint64_t *a2 = self.a2
  __pyx_t_12 = __pyx_v_self->a2;
  __pyx_v_a2 = __pyx_t_12;
+163:         cdef uint16_t l = self.height
  __pyx_t_13 = __pyx_v_self->height;
  __pyx_v_l = __pyx_t_13;
 164:         cdef uint16_t y1, y2
+165:         cdef uint16_t miny=0, maxy=0
  __pyx_v_miny = 0;
  __pyx_v_maxy = 0;
 166:         cdef uint64_t a2v
+167:         if self.distances==NULL:
  __pyx_t_1 = ((__pyx_v_self->distances == NULL) != 0);
  if (__pyx_t_1) {
/* … */
  }
+168:             self.distances = <uint16_t*> memalign(2*l*sizeof(uint16_t))
    __pyx_v_self->distances = ((uint16_t *)__pyx_f_4xpra_7buffers_6membuf_memalign(((2 * __pyx_v_l) * (sizeof(uint16_t)))));
+169:             assert self.distances!=NULL, "distance memory allocation failed"
    #ifndef CYTHON_WITHOUT_ASSERTIONS
    if (unlikely(!Py_OptimizeFlag)) {
      if (unlikely(!((__pyx_v_self->distances != NULL) != 0))) {
        PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_distance_memory_allocation_faile);
        __PYX_ERR(0, 169, __pyx_L1_error)
      }
    }
    #endif
+170:         cdef uint16_t matches = 0
  __pyx_v_matches = 0;
+171:         with nogil:
  {
      #ifdef WITH_THREAD
      PyThreadState *_save;
      Py_UNBLOCK_THREADS
      __Pyx_FastGIL_Remember();
      #endif
      /*try:*/ {
/* … */
      /*finally:*/ {
        /*normal exit:*/{
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L10;
        }
        __pyx_L10:;
      }
  }
+172:             memset(self.distances, 0, 2*l*sizeof(uint16_t))
        (void)(memset(__pyx_v_self->distances, 0, ((2 * __pyx_v_l) * (sizeof(uint16_t)))));
+173:             for y2 in range(l):
        __pyx_t_13 = __pyx_v_l;
        __pyx_t_14 = __pyx_t_13;
        for (__pyx_t_15 = 0; __pyx_t_15 < __pyx_t_14; __pyx_t_15+=1) {
          __pyx_v_y2 = __pyx_t_15;
 174:                 #miny = max(0, y2-max_distance):
+175:                 if y2>max_distance:
          __pyx_t_1 = ((__pyx_v_y2 > __pyx_v_max_distance) != 0);
          if (__pyx_t_1) {
/* … */
            goto __pyx_L13;
          }
+176:                     miny = y2-max_distance
            __pyx_v_miny = (__pyx_v_y2 - __pyx_v_max_distance);
 177:                 else:
+178:                     miny = 0
          /*else*/ {
            __pyx_v_miny = 0;
          }
          __pyx_L13:;
 179:                 #maxy = min(l, y2+max_distance)
+180:                 if y2+max_distance<l:
          __pyx_t_1 = (((__pyx_v_y2 + __pyx_v_max_distance) < __pyx_v_l) != 0);
          if (__pyx_t_1) {
/* … */
            goto __pyx_L14;
          }
+181:                     maxy = y2+max_distance
            __pyx_v_maxy = (__pyx_v_y2 + __pyx_v_max_distance);
 182:                 else:
+183:                     maxy = l
          /*else*/ {
            __pyx_v_maxy = __pyx_v_l;
          }
          __pyx_L14:;
+184:                 a2v = a2[y2]
          __pyx_v_a2v = (__pyx_v_a2[__pyx_v_y2]);
+185:                 if a2v==0:
          __pyx_t_1 = ((__pyx_v_a2v == 0) != 0);
          if (__pyx_t_1) {
/* … */
          }
+186:                     continue
            goto __pyx_L11_continue;
+187:                 for y1 in range(miny, maxy):
          __pyx_t_16 = __pyx_v_maxy;
          __pyx_t_17 = __pyx_t_16;
          for (__pyx_t_18 = __pyx_v_miny; __pyx_t_18 < __pyx_t_17; __pyx_t_18+=1) {
            __pyx_v_y1 = __pyx_t_18;
+188:                     if a1[y1]==a2v:
            __pyx_t_1 = (((__pyx_v_a1[__pyx_v_y1]) == __pyx_v_a2v) != 0);
            if (__pyx_t_1) {
/* … */
            }
          }
          __pyx_L11_continue:;
        }
      }
 189:                         #distance = y1-y2
+190:                         self.distances[l-(y1-y2)] += 1
              __pyx_t_9 = (__pyx_v_l - (__pyx_v_y1 - __pyx_v_y2));
              (__pyx_v_self->distances[__pyx_t_9]) = ((__pyx_v_self->distances[__pyx_t_9]) + 1);
+191:                         matches += 1
              __pyx_v_matches = (__pyx_v_matches + 1);
+192:         if DEBUG:
  __pyx_t_1 = (__pyx_v_4xpra_6server_6window_6motion_DEBUG != 0);
  if (__pyx_t_1) {
/* … */
  }
+193:             log("ScrollDistance: height=%i, calculate:", l)
    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_log); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 193, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_10 = __Pyx_PyInt_From_uint16_t(__pyx_v_l); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 193, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_10);
    __pyx_t_7 = NULL;
    __pyx_t_9 = 0;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
      __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_3);
      if (likely(__pyx_t_7)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
        __Pyx_INCREF(__pyx_t_7);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_3, function);
        __pyx_t_9 = 1;
      }
    }
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_kp_s_ScrollDistance_height_i_calculat, __pyx_t_10};
      __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 193, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[3] = {__pyx_t_7, __pyx_kp_s_ScrollDistance_height_i_calculat, __pyx_t_10};
      __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 193, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
    } else
    #endif
    {
      __pyx_t_6 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 193, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      if (__pyx_t_7) {
        __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_7); __pyx_t_7 = NULL;
      }
      __Pyx_INCREF(__pyx_kp_s_ScrollDistance_height_i_calculat);
      __Pyx_GIVEREF(__pyx_kp_s_ScrollDistance_height_i_calculat);
      PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_9, __pyx_kp_s_ScrollDistance_height_i_calculat);
      __Pyx_GIVEREF(__pyx_t_10);
      PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_9, __pyx_t_10);
      __pyx_t_10 = 0;
      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 193, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    }
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+194:             log(" a1=%s", da(self.a1, l))
    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_log); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 194, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_6 = __pyx_f_4xpra_6server_6window_6motion_da(__pyx_v_self->a1, __pyx_v_l); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 194, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_10 = NULL;
    __pyx_t_9 = 0;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
      __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_3);
      if (likely(__pyx_t_10)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
        __Pyx_INCREF(__pyx_t_10);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_3, function);
        __pyx_t_9 = 1;
      }
    }
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[3] = {__pyx_t_10, __pyx_kp_s_a1_s, __pyx_t_6};
      __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 194, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[3] = {__pyx_t_10, __pyx_kp_s_a1_s, __pyx_t_6};
      __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 194, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    } else
    #endif
    {
      __pyx_t_7 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 194, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_7);
      if (__pyx_t_10) {
        __Pyx_GIVEREF(__pyx_t_10); PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_t_10); __pyx_t_10 = NULL;
      }
      __Pyx_INCREF(__pyx_kp_s_a1_s);
      __Pyx_GIVEREF(__pyx_kp_s_a1_s);
      PyTuple_SET_ITEM(__pyx_t_7, 0+__pyx_t_9, __pyx_kp_s_a1_s);
      __Pyx_GIVEREF(__pyx_t_6);
      PyTuple_SET_ITEM(__pyx_t_7, 1+__pyx_t_9, __pyx_t_6);
      __pyx_t_6 = 0;
      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_7, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 194, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    }
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+195:             log(" a2=%s", da(self.a2, l))
    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_log); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 195, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_7 = __pyx_f_4xpra_6server_6window_6motion_da(__pyx_v_self->a2, __pyx_v_l); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 195, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __pyx_t_6 = NULL;
    __pyx_t_9 = 0;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
      if (likely(__pyx_t_6)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
        __Pyx_INCREF(__pyx_t_6);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_3, function);
        __pyx_t_9 = 1;
      }
    }
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_kp_s_a2_s, __pyx_t_7};
      __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 195, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[3] = {__pyx_t_6, __pyx_kp_s_a2_s, __pyx_t_7};
      __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 195, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    } else
    #endif
    {
      __pyx_t_10 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 195, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      if (__pyx_t_6) {
        __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_6); __pyx_t_6 = NULL;
      }
      __Pyx_INCREF(__pyx_kp_s_a2_s);
      __Pyx_GIVEREF(__pyx_kp_s_a2_s);
      PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, __pyx_kp_s_a2_s);
      __Pyx_GIVEREF(__pyx_t_7);
      PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_t_7);
      __pyx_t_7 = 0;
      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_10, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 195, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
    }
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+196:             log(" %i matches, distances=%s", matches, dd(self.distances, l*2))
    __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_log); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 196, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_10 = __Pyx_PyInt_From_uint16_t(__pyx_v_matches); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 196, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_10);
    __pyx_t_7 = __pyx_f_4xpra_6server_6window_6motion_dd(__pyx_v_self->distances, (__pyx_v_l * 2)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 196, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_7);
    __pyx_t_6 = NULL;
    __pyx_t_9 = 0;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
      __pyx_t_6 = PyMethod_GET_SELF(__pyx_t_3);
      if (likely(__pyx_t_6)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
        __Pyx_INCREF(__pyx_t_6);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_3, function);
        __pyx_t_9 = 1;
      }
    }
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[4] = {__pyx_t_6, __pyx_kp_s_i_matches_distances_s, __pyx_t_10, __pyx_t_7};
      __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 3+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 196, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
      PyObject *__pyx_temp[4] = {__pyx_t_6, __pyx_kp_s_i_matches_distances_s, __pyx_t_10, __pyx_t_7};
      __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 3+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 196, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0;
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    } else
    #endif
    {
      __pyx_t_5 = PyTuple_New(3+__pyx_t_9); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 196, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      if (__pyx_t_6) {
        __Pyx_GIVEREF(__pyx_t_6); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_6); __pyx_t_6 = NULL;
      }
      __Pyx_INCREF(__pyx_kp_s_i_matches_distances_s);
      __Pyx_GIVEREF(__pyx_kp_s_i_matches_distances_s);
      PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_9, __pyx_kp_s_i_matches_distances_s);
      __Pyx_GIVEREF(__pyx_t_10);
      PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_9, __pyx_t_10);
      __Pyx_GIVEREF(__pyx_t_7);
      PyTuple_SET_ITEM(__pyx_t_5, 2+__pyx_t_9, __pyx_t_7);
      __pyx_t_10 = 0;
      __pyx_t_7 = 0;
      __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_5, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 196, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    }
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 197: 
+198:     def get_scroll_values(self, uint16_t min_hits=2):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_11get_scroll_values(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_4xpra_6server_6window_6motion_10ScrollData_10get_scroll_values[] = "\n            Return two dictionaries that describe how to go from a1 to a2.\n            * scrolls dictionary contains scroll definitions\n            * non-scrolls dictionary is everything else (that will need to be repainted)\n        ";
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_11get_scroll_values(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  uint16_t __pyx_v_min_hits;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("get_scroll_values (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_min_hits,0};
    PyObject* values[1] = {0};
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (kw_args > 0) {
          PyObject* value = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_min_hits);
          if (value) { values[0] = value; kw_args--; }
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "get_scroll_values") < 0)) __PYX_ERR(0, 198, __pyx_L3_error)
      }
    } else {
      switch (PyTuple_GET_SIZE(__pyx_args)) {
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
    }
    if (values[0]) {
      __pyx_v_min_hits = __Pyx_PyInt_As_uint16_t(values[0]); if (unlikely((__pyx_v_min_hits == ((uint16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 198, __pyx_L3_error)
    } else {
      __pyx_v_min_hits = ((uint16_t)2);
    }
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("get_scroll_values", 0, 0, 1, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 198, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("xpra.server.window.motion.ScrollData.get_scroll_values", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_4xpra_6server_6window_6motion_10ScrollData_10get_scroll_values(((struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *)__pyx_v_self), __pyx_v_min_hits);

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_6window_6motion_10ScrollData_10get_scroll_values(struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *__pyx_v_self, uint16_t __pyx_v_min_hits) {
  uint16_t __pyx_v_m_arr[20];
  int16_t __pyx_v_s_arr[20];
  int16_t __pyx_v_i;
  uint8_t __pyx_v_j;
  int16_t __pyx_v_low;
  int16_t __pyx_v_matches;
  uint16_t *__pyx_v_distances;
  uint16_t __pyx_v_l;
  size_t __pyx_v_asize;
  uint8_t *__pyx_v_line_state;
  PyObject *__pyx_v_scroll_hits = NULL;
  uint16_t __pyx_v_start;
  uint16_t __pyx_v_count;
  PyObject *__pyx_v_scrolls = NULL;
  PyObject *__pyx_v_v = NULL;
  PyObject *__pyx_v_scroll = NULL;
  PyObject *__pyx_v_line_defs = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("get_scroll_values", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_9);
  __Pyx_XDECREF(__pyx_t_10);
  __Pyx_XDECREF(__pyx_t_11);
  __Pyx_XDECREF(__pyx_t_14);
  __Pyx_AddTraceback("xpra.server.window.motion.ScrollData.get_scroll_values", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_scroll_hits);
  __Pyx_XDECREF(__pyx_v_scrolls);
  __Pyx_XDECREF(__pyx_v_v);
  __Pyx_XDECREF(__pyx_v_scroll);
  __Pyx_XDECREF(__pyx_v_line_defs);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 199:         """
 200:             Return two dictionaries that describe how to go from a1 to a2.
 201:             * scrolls dictionary contains scroll definitions
 202:             * non-scrolls dictionary is everything else (that will need to be repainted)
 203:         """
 204:         DEF MAX_MATCHES = 20
+205:         if self.a1==NULL or self.a2==NULL:
  __pyx_t_2 = ((__pyx_v_self->a1 == NULL) != 0);
  if (!__pyx_t_2) {
  } else {
    __pyx_t_1 = __pyx_t_2;
    goto __pyx_L4_bool_binop_done;
  }
  __pyx_t_2 = ((__pyx_v_self->a2 == NULL) != 0);
  __pyx_t_1 = __pyx_t_2;
  __pyx_L4_bool_binop_done:;
  if (__pyx_t_1) {
/* … */
  }
+206:             return None
    __Pyx_XDECREF(__pyx_r);
    __pyx_r = Py_None; __Pyx_INCREF(Py_None);
    goto __pyx_L0;
 207:         cdef uint16_t m_arr[MAX_MATCHES]    #number of hits
 208:         cdef int16_t s_arr[MAX_MATCHES]     #scroll distance
 209:         cdef int16_t i
 210:         cdef uint8_t j
+211:         cdef int16_t low = 0                #the lowest match value
  __pyx_v_low = 0;
 212:         cdef int16_t matches
+213:         cdef uint16_t* distances = self.distances
  __pyx_t_3 = __pyx_v_self->distances;
  __pyx_v_distances = __pyx_t_3;
+214:         cdef uint16_t l = self.height
  __pyx_t_4 = __pyx_v_self->height;
  __pyx_v_l = __pyx_t_4;
+215:         cdef size_t asize = l*(sizeof(uint8_t))
  __pyx_v_asize = (__pyx_v_l * (sizeof(uint8_t)));
 216:         #use a temporary buffer to track the lines we have already dealt with:
+217:         cdef uint8_t *line_state = <uint8_t*> malloc(asize)
  __pyx_v_line_state = ((uint8_t *)malloc(__pyx_v_asize));
+218:         assert line_state!=NULL, "state map memory allocation failed"
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    if (unlikely(!((__pyx_v_line_state != NULL) != 0))) {
      PyErr_SetObject(PyExc_AssertionError, __pyx_kp_s_state_map_memory_allocation_fail);
      __PYX_ERR(0, 218, __pyx_L1_error)
    }
  }
  #endif
 219:         #find the best values (highest match count):
+220:         with nogil:
  {
      #ifdef WITH_THREAD
      PyThreadState *_save;
      Py_UNBLOCK_THREADS
      __Pyx_FastGIL_Remember();
      #endif
      /*try:*/ {
/* … */
      /*finally:*/ {
        /*normal exit:*/{
          #ifdef WITH_THREAD
          __Pyx_FastGIL_Forget();
          Py_BLOCK_THREADS
          #endif
          goto __pyx_L8;
        }
        __pyx_L8:;
      }
  }
+221:             memset(line_state, 0, asize)
        (void)(memset(__pyx_v_line_state, 0, __pyx_v_asize));
+222:             memset(m_arr, 0, MAX_MATCHES*sizeof(uint16_t))
        (void)(memset(__pyx_v_m_arr, 0, (20 * (sizeof(uint16_t)))));
+223:             memset(s_arr, 0, MAX_MATCHES*sizeof(int16_t))
        (void)(memset(__pyx_v_s_arr, 0, (20 * (sizeof(int16_t)))));
+224:             for i in range(2*l):
        __pyx_t_5 = (2 * __pyx_v_l);
        __pyx_t_6 = __pyx_t_5;
        for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_6; __pyx_t_7+=1) {
          __pyx_v_i = __pyx_t_7;
+225:                 matches = distances[i]
          __pyx_v_matches = (__pyx_v_distances[__pyx_v_i]);
+226:                 if matches>low and matches>min_hits:
          __pyx_t_2 = ((__pyx_v_matches > __pyx_v_low) != 0);
          if (__pyx_t_2) {
          } else {
            __pyx_t_1 = __pyx_t_2;
            goto __pyx_L12_bool_binop_done;
          }
          __pyx_t_2 = ((__pyx_v_matches > __pyx_v_min_hits) != 0);
          __pyx_t_1 = __pyx_t_2;
          __pyx_L12_bool_binop_done:;
          if (__pyx_t_1) {
/* … */
          }
        }
      }
 227:                     #add this candidate match to the arrays:
 228:                     #find the lowest score index and replace it:
+229:                     for j in range(MAX_MATCHES):
            for (__pyx_t_8 = 0; __pyx_t_8 < 20; __pyx_t_8+=1) {
              __pyx_v_j = __pyx_t_8;
+230:                         if m_arr[j]==low:
              __pyx_t_1 = (((__pyx_v_m_arr[__pyx_v_j]) == __pyx_v_low) != 0);
              if (__pyx_t_1) {
/* … */
              }
            }
            __pyx_L15_break:;
+231:                             break
                goto __pyx_L15_break;
+232:                     m_arr[j] = matches
            (__pyx_v_m_arr[__pyx_v_j]) = __pyx_v_matches;
+233:                     s_arr[j] = i-l
            (__pyx_v_s_arr[__pyx_v_j]) = (__pyx_v_i - __pyx_v_l);
 234:                     #find the new lowest value we have:
+235:                     low = matches
            __pyx_v_low = __pyx_v_matches;
+236:                     for j in range(MAX_MATCHES):
            for (__pyx_t_8 = 0; __pyx_t_8 < 20; __pyx_t_8+=1) {
              __pyx_v_j = __pyx_t_8;
+237:                         if m_arr[j]<low:
              __pyx_t_1 = (((__pyx_v_m_arr[__pyx_v_j]) < __pyx_v_low) != 0);
              if (__pyx_t_1) {
/* … */
              }
            }
            __pyx_L18_break:;
+238:                             low = m_arr[j]
                __pyx_v_low = (__pyx_v_m_arr[__pyx_v_j]);
+239:                             if low==0:
                __pyx_t_1 = ((__pyx_v_low == 0) != 0);
                if (__pyx_t_1) {
/* … */
                }
+240:                                 break
                  goto __pyx_L18_break;
 241:         #first collect the list of distances sorted by highest number of matches:
 242:         #(there can be more than one distance value for each match count):
+243:         scroll_hits = {}
  __pyx_t_9 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 243, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_9);
  __pyx_v_scroll_hits = ((PyObject*)__pyx_t_9);
  __pyx_t_9 = 0;
+244:         for i in range(MAX_MATCHES):
  for (__pyx_t_7 = 0; __pyx_t_7 < 20; __pyx_t_7+=1) {
    __pyx_v_i = __pyx_t_7;
+245:             if m_arr[i]>min_hits:
    __pyx_t_1 = (((__pyx_v_m_arr[__pyx_v_i]) > __pyx_v_min_hits) != 0);
    if (__pyx_t_1) {
/* … */
    }
  }
+246:                 scroll_hits.setdefault(m_arr[i], []).append(s_arr[i])
      __pyx_t_9 = __Pyx_PyInt_From_uint16_t((__pyx_v_m_arr[__pyx_v_i])); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 246, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_9);
      __pyx_t_10 = PyList_New(0); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 246, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      __pyx_t_11 = __Pyx_PyDict_SetDefault(__pyx_v_scroll_hits, __pyx_t_9, __pyx_t_10, -1L); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 246, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0;
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      __pyx_t_10 = __Pyx_PyInt_From_int16_t((__pyx_v_s_arr[__pyx_v_i])); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 246, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      __pyx_t_12 = __Pyx_PyObject_Append(__pyx_t_11, __pyx_t_10); if (unlikely(__pyx_t_12 == ((int)-1))) __PYX_ERR(0, 246, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
+247:         if DEBUG:
  __pyx_t_1 = (__pyx_v_4xpra_6server_6window_6motion_DEBUG != 0);
  if (__pyx_t_1) {
/* … */
  }
+248:             log("scroll hits=%s", scroll_hits)
    __pyx_t_11 = __Pyx_GetModuleGlobalName(__pyx_n_s_log); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 248, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_11);
    __pyx_t_9 = NULL;
    __pyx_t_13 = 0;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_11))) {
      __pyx_t_9 = PyMethod_GET_SELF(__pyx_t_11);
      if (likely(__pyx_t_9)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_11);
        __Pyx_INCREF(__pyx_t_9);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_11, function);
        __pyx_t_13 = 1;
      }
    }
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_11)) {
      PyObject *__pyx_temp[3] = {__pyx_t_9, __pyx_kp_s_scroll_hits_s, __pyx_v_scroll_hits};
      __pyx_t_10 = __Pyx_PyFunction_FastCall(__pyx_t_11, __pyx_temp+1-__pyx_t_13, 2+__pyx_t_13); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 248, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
      __Pyx_GOTREF(__pyx_t_10);
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_11)) {
      PyObject *__pyx_temp[3] = {__pyx_t_9, __pyx_kp_s_scroll_hits_s, __pyx_v_scroll_hits};
      __pyx_t_10 = __Pyx_PyCFunction_FastCall(__pyx_t_11, __pyx_temp+1-__pyx_t_13, 2+__pyx_t_13); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 248, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
      __Pyx_GOTREF(__pyx_t_10);
    } else
    #endif
    {
      __pyx_t_14 = PyTuple_New(2+__pyx_t_13); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 248, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_14);
      if (__pyx_t_9) {
        __Pyx_GIVEREF(__pyx_t_9); PyTuple_SET_ITEM(__pyx_t_14, 0, __pyx_t_9); __pyx_t_9 = NULL;
      }
      __Pyx_INCREF(__pyx_kp_s_scroll_hits_s);
      __Pyx_GIVEREF(__pyx_kp_s_scroll_hits_s);
      PyTuple_SET_ITEM(__pyx_t_14, 0+__pyx_t_13, __pyx_kp_s_scroll_hits_s);
      __Pyx_INCREF(__pyx_v_scroll_hits);
      __Pyx_GIVEREF(__pyx_v_scroll_hits);
      PyTuple_SET_ITEM(__pyx_t_14, 1+__pyx_t_13, __pyx_v_scroll_hits);
      __pyx_t_10 = __Pyx_PyObject_Call(__pyx_t_11, __pyx_t_14, NULL); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 248, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_10);
      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
    }
    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
 249:         #return a dict with the scroll distance as key,
 250:         #and the list of matching lines in a dictionary:
 251:         # {line-start : count, ..}
+252:         cdef uint16_t start = 0, count = 0
  __pyx_v_start = 0;
  __pyx_v_count = 0;
+253:         try:
  /*try:*/ {
+254:             scrolls = collections.OrderedDict()
    __pyx_t_11 = __Pyx_GetModuleGlobalName(__pyx_n_s_collections); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 254, __pyx_L26_error)
    __Pyx_GOTREF(__pyx_t_11);
    __pyx_t_14 = __Pyx_PyObject_GetAttrStr(__pyx_t_11, __pyx_n_s_OrderedDict); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 254, __pyx_L26_error)
    __Pyx_GOTREF(__pyx_t_14);
    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
    __pyx_t_11 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_14))) {
      __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_14);
      if (likely(__pyx_t_11)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_14);
        __Pyx_INCREF(__pyx_t_11);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_14, function);
      }
    }
    if (__pyx_t_11) {
      __pyx_t_10 = __Pyx_PyObject_CallOneArg(__pyx_t_14, __pyx_t_11); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 254, __pyx_L26_error)
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
    } else {
      __pyx_t_10 = __Pyx_PyObject_CallNoArg(__pyx_t_14); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 254, __pyx_L26_error)
    }
    __Pyx_GOTREF(__pyx_t_10);
    __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
    __pyx_v_scrolls = __pyx_t_10;
    __pyx_t_10 = 0;
 255:             #starting with the highest matches
+256:             for i in reversed(sorted(scroll_hits.keys())):
    __pyx_t_14 = __Pyx_PyDict_Keys(__pyx_v_scroll_hits); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 256, __pyx_L26_error)
    __Pyx_GOTREF(__pyx_t_14);
    __pyx_t_11 = PySequence_List(__pyx_t_14); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 256, __pyx_L26_error)
    __Pyx_GOTREF(__pyx_t_11);
    __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
    __pyx_t_10 = ((PyObject*)__pyx_t_11);
    __pyx_t_11 = 0;
    __pyx_t_12 = PyList_Sort(__pyx_t_10); if (unlikely(__pyx_t_12 == ((int)-1))) __PYX_ERR(0, 256, __pyx_L26_error)
    if (unlikely(__pyx_t_10 == Py_None)) {
      PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable");
      __PYX_ERR(0, 256, __pyx_L26_error)
    }
    __pyx_t_11 = __pyx_t_10; __Pyx_INCREF(__pyx_t_11); __pyx_t_15 = PyList_GET_SIZE(__pyx_t_11) - 1;
    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
    for (;;) {
      if (__pyx_t_15 < 0) break;
      if (__pyx_t_15 >= PyList_GET_SIZE(__pyx_t_11)) break;
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      __pyx_t_10 = PyList_GET_ITEM(__pyx_t_11, __pyx_t_15); __Pyx_INCREF(__pyx_t_10); __pyx_t_15--; if (unlikely(0 < 0)) __PYX_ERR(0, 256, __pyx_L26_error)
      #else
      __pyx_t_10 = PySequence_ITEM(__pyx_t_11, __pyx_t_15); __pyx_t_15--; if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 256, __pyx_L26_error)
      __Pyx_GOTREF(__pyx_t_10);
      #endif
      __pyx_t_7 = __Pyx_PyInt_As_int16_t(__pyx_t_10); if (unlikely((__pyx_t_7 == ((int16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 256, __pyx_L26_error)
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      __pyx_v_i = __pyx_t_7;
/* … */
    }
    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+257:                 v = scroll_hits[i]
      __pyx_t_10 = __Pyx_PyInt_From_int16_t(__pyx_v_i); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 257, __pyx_L26_error)
      __Pyx_GOTREF(__pyx_t_10);
      __pyx_t_14 = __Pyx_PyDict_GetItem(__pyx_v_scroll_hits, __pyx_t_10); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 257, __pyx_L26_error)
      __Pyx_GOTREF(__pyx_t_14);
      __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
      __Pyx_XDECREF_SET(__pyx_v_v, __pyx_t_14);
      __pyx_t_14 = 0;
+258:                 for scroll in v:
      if (likely(PyList_CheckExact(__pyx_v_v)) || PyTuple_CheckExact(__pyx_v_v)) {
        __pyx_t_14 = __pyx_v_v; __Pyx_INCREF(__pyx_t_14); __pyx_t_16 = 0;
        __pyx_t_17 = NULL;
      } else {
        __pyx_t_16 = -1; __pyx_t_14 = PyObject_GetIter(__pyx_v_v); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 258, __pyx_L26_error)
        __Pyx_GOTREF(__pyx_t_14);
        __pyx_t_17 = Py_TYPE(__pyx_t_14)->tp_iternext; if (unlikely(!__pyx_t_17)) __PYX_ERR(0, 258, __pyx_L26_error)
      }
      for (;;) {
        if (likely(!__pyx_t_17)) {
          if (likely(PyList_CheckExact(__pyx_t_14))) {
            if (__pyx_t_16 >= PyList_GET_SIZE(__pyx_t_14)) break;
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_10 = PyList_GET_ITEM(__pyx_t_14, __pyx_t_16); __Pyx_INCREF(__pyx_t_10); __pyx_t_16++; if (unlikely(0 < 0)) __PYX_ERR(0, 258, __pyx_L26_error)
            #else
            __pyx_t_10 = PySequence_ITEM(__pyx_t_14, __pyx_t_16); __pyx_t_16++; if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 258, __pyx_L26_error)
            __Pyx_GOTREF(__pyx_t_10);
            #endif
          } else {
            if (__pyx_t_16 >= PyTuple_GET_SIZE(__pyx_t_14)) break;
            #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
            __pyx_t_10 = PyTuple_GET_ITEM(__pyx_t_14, __pyx_t_16); __Pyx_INCREF(__pyx_t_10); __pyx_t_16++; if (unlikely(0 < 0)) __PYX_ERR(0, 258, __pyx_L26_error)
            #else
            __pyx_t_10 = PySequence_ITEM(__pyx_t_14, __pyx_t_16); __pyx_t_16++; if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 258, __pyx_L26_error)
            __Pyx_GOTREF(__pyx_t_10);
            #endif
          }
        } else {
          __pyx_t_10 = __pyx_t_17(__pyx_t_14);
          if (unlikely(!__pyx_t_10)) {
            PyObject* exc_type = PyErr_Occurred();
            if (exc_type) {
              if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
              else __PYX_ERR(0, 258, __pyx_L26_error)
            }
            break;
          }
          __Pyx_GOTREF(__pyx_t_10);
        }
        __Pyx_XDECREF_SET(__pyx_v_scroll, __pyx_t_10);
        __pyx_t_10 = 0;
/* … */
      }
      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
 259:                     #find matching lines:
+260:                     line_defs = self.match_distance(line_state, scroll)
        __pyx_t_7 = __Pyx_PyInt_As_int16_t(__pyx_v_scroll); if (unlikely((__pyx_t_7 == ((int16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 260, __pyx_L26_error)
        __pyx_t_10 = ((struct __pyx_vtabstruct_4xpra_6server_6window_6motion_ScrollData *)__pyx_v_self->__pyx_vtab)->match_distance(__pyx_v_self, __pyx_v_line_state, __pyx_t_7); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 260, __pyx_L26_error)
        __Pyx_GOTREF(__pyx_t_10);
        __Pyx_XDECREF_SET(__pyx_v_line_defs, __pyx_t_10);
        __pyx_t_10 = 0;
+261:                     if line_defs:
        __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_line_defs); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 261, __pyx_L26_error)
        if (__pyx_t_1) {
/* … */
        }
+262:                         scrolls[scroll] = line_defs
          if (unlikely(PyObject_SetItem(__pyx_v_scrolls, __pyx_v_scroll, __pyx_v_line_defs) < 0)) __PYX_ERR(0, 262, __pyx_L26_error)
 263:             #same for the unmatched lines:
 264:             #all the lines in tmp which have not been set by match_distance()
+265:             line_defs = collections.OrderedDict()
    __pyx_t_14 = __Pyx_GetModuleGlobalName(__pyx_n_s_collections); if (unlikely(!__pyx_t_14)) __PYX_ERR(0, 265, __pyx_L26_error)
    __Pyx_GOTREF(__pyx_t_14);
    __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_t_14, __pyx_n_s_OrderedDict); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 265, __pyx_L26_error)
    __Pyx_GOTREF(__pyx_t_10);
    __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
    __pyx_t_14 = NULL;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_10))) {
      __pyx_t_14 = PyMethod_GET_SELF(__pyx_t_10);
      if (likely(__pyx_t_14)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_10);
        __Pyx_INCREF(__pyx_t_14);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_10, function);
      }
    }
    if (__pyx_t_14) {
      __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_t_10, __pyx_t_14); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 265, __pyx_L26_error)
      __Pyx_DECREF(__pyx_t_14); __pyx_t_14 = 0;
    } else {
      __pyx_t_11 = __Pyx_PyObject_CallNoArg(__pyx_t_10); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 265, __pyx_L26_error)
    }
    __Pyx_GOTREF(__pyx_t_11);
    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
    __Pyx_XDECREF_SET(__pyx_v_line_defs, __pyx_t_11);
    __pyx_t_11 = 0;
+266:             for i in range(l):
    __pyx_t_4 = __pyx_v_l;
    __pyx_t_18 = __pyx_t_4;
    for (__pyx_t_7 = 0; __pyx_t_7 < __pyx_t_18; __pyx_t_7+=1) {
      __pyx_v_i = __pyx_t_7;
+267:                 if line_state[i]==0:
      __pyx_t_1 = (((__pyx_v_line_state[__pyx_v_i]) == 0) != 0);
      if (__pyx_t_1) {
/* … */
        goto __pyx_L35;
      }
+268:                     if count==0:
        __pyx_t_1 = ((__pyx_v_count == 0) != 0);
        if (__pyx_t_1) {
/* … */
        }
+269:                         start = i
          __pyx_v_start = __pyx_v_i;
+270:                     count += 1
        __pyx_v_count = (__pyx_v_count + 1);
+271:                 elif count>0:
      __pyx_t_1 = ((__pyx_v_count > 0) != 0);
      if (__pyx_t_1) {
/* … */
      }
      __pyx_L35:;
    }
+272:                     line_defs[start] = count
        __pyx_t_11 = __Pyx_PyInt_From_uint16_t(__pyx_v_count); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 272, __pyx_L26_error)
        __Pyx_GOTREF(__pyx_t_11);
        if (unlikely(__Pyx_SetItemInt(__pyx_v_line_defs, __pyx_v_start, __pyx_t_11, uint16_t, 0, __Pyx_PyInt_From_uint16_t, 0, 0, 0) < 0)) __PYX_ERR(0, 272, __pyx_L26_error)
        __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
+273:                     count = 0
        __pyx_v_count = 0;
+274:             if count>0:
    __pyx_t_1 = ((__pyx_v_count > 0) != 0);
    if (__pyx_t_1) {
/* … */
    }
  }
+275:                 line_defs[start] = count
      __pyx_t_11 = __Pyx_PyInt_From_uint16_t(__pyx_v_count); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 275, __pyx_L26_error)
      __Pyx_GOTREF(__pyx_t_11);
      if (unlikely(__Pyx_SetItemInt(__pyx_v_line_defs, __pyx_v_start, __pyx_t_11, uint16_t, 0, __Pyx_PyInt_From_uint16_t, 0, 0, 0) < 0)) __PYX_ERR(0, 275, __pyx_L26_error)
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
 276:         finally:
+277:             free(line_state)
  /*finally:*/ {
    /*normal exit:*/{
      free(__pyx_v_line_state);
      goto __pyx_L27;
    }
    __pyx_L26_error:;
    /*exception exit:*/{
      __Pyx_PyThreadState_declare
      __Pyx_PyThreadState_assign
      __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0; __pyx_t_24 = 0; __pyx_t_25 = 0; __pyx_t_26 = 0;
      __Pyx_XDECREF(__pyx_t_9); __pyx_t_9 = 0;
      __Pyx_XDECREF(__pyx_t_14); __pyx_t_14 = 0;
      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
      __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0;
      if (PY_MAJOR_VERSION >= 3) __Pyx_ExceptionSwap(&__pyx_t_24, &__pyx_t_25, &__pyx_t_26);
      if ((PY_MAJOR_VERSION < 3) || unlikely(__Pyx_GetException(&__pyx_t_21, &__pyx_t_22, &__pyx_t_23) < 0)) __Pyx_ErrFetch(&__pyx_t_21, &__pyx_t_22, &__pyx_t_23);
      __Pyx_XGOTREF(__pyx_t_21);
      __Pyx_XGOTREF(__pyx_t_22);
      __Pyx_XGOTREF(__pyx_t_23);
      __Pyx_XGOTREF(__pyx_t_24);
      __Pyx_XGOTREF(__pyx_t_25);
      __Pyx_XGOTREF(__pyx_t_26);
      __pyx_t_13 = __pyx_lineno; __pyx_t_19 = __pyx_clineno; __pyx_t_20 = __pyx_filename;
      {
        free(__pyx_v_line_state);
      }
      if (PY_MAJOR_VERSION >= 3) {
        __Pyx_XGIVEREF(__pyx_t_24);
        __Pyx_XGIVEREF(__pyx_t_25);
        __Pyx_XGIVEREF(__pyx_t_26);
        __Pyx_ExceptionReset(__pyx_t_24, __pyx_t_25, __pyx_t_26);
      }
      __Pyx_XGIVEREF(__pyx_t_21);
      __Pyx_XGIVEREF(__pyx_t_22);
      __Pyx_XGIVEREF(__pyx_t_23);
      __Pyx_ErrRestore(__pyx_t_21, __pyx_t_22, __pyx_t_23);
      __pyx_t_21 = 0; __pyx_t_22 = 0; __pyx_t_23 = 0; __pyx_t_24 = 0; __pyx_t_25 = 0; __pyx_t_26 = 0;
      __pyx_lineno = __pyx_t_13; __pyx_clineno = __pyx_t_19; __pyx_filename = __pyx_t_20;
      goto __pyx_L1_error;
    }
    __pyx_L27:;
  }
+278:         return scrolls, line_defs
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_11 = PyTuple_New(2); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 278, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_11);
  __Pyx_INCREF(__pyx_v_scrolls);
  __Pyx_GIVEREF(__pyx_v_scrolls);
  PyTuple_SET_ITEM(__pyx_t_11, 0, __pyx_v_scrolls);
  __Pyx_INCREF(__pyx_v_line_defs);
  __Pyx_GIVEREF(__pyx_v_line_defs);
  PyTuple_SET_ITEM(__pyx_t_11, 1, __pyx_v_line_defs);
  __pyx_r = __pyx_t_11;
  __pyx_t_11 = 0;
  goto __pyx_L0;
 279: 
+280:     cdef match_distance(self, uint8_t *line_state, int16_t distance):
static PyObject *__pyx_f_4xpra_6server_6window_6motion_10ScrollData_match_distance(struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *__pyx_v_self, uint8_t *__pyx_v_line_state, int16_t __pyx_v_distance) {
  uint64_t *__pyx_v_a1;
  uint64_t *__pyx_v_a2;
  uint16_t __pyx_v_rstart;
  uint16_t __pyx_v_rend;
  uint16_t __pyx_v_i1;
  uint16_t __pyx_v_i2;
  uint16_t __pyx_v_start;
  uint16_t __pyx_v_count;
  PyObject *__pyx_v_line_defs = NULL;
  PyObject *__pyx_v_i = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("match_distance", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_11);
  __Pyx_XDECREF(__pyx_t_12);
  __Pyx_AddTraceback("xpra.server.window.motion.ScrollData.match_distance", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = 0;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_line_defs);
  __Pyx_XDECREF(__pyx_v_i);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
 281:         """
 282:             find the lines that match the given scroll distance,
 283:             return a dictionary with the starting line as key
 284:             and the number of matching lines as value
 285:         """
+286:         cdef uint64_t *a1 = self.a1
  __pyx_t_1 = __pyx_v_self->a1;
  __pyx_v_a1 = __pyx_t_1;
+287:         cdef uint64_t *a2 = self.a2
  __pyx_t_1 = __pyx_v_self->a2;
  __pyx_v_a2 = __pyx_t_1;
+288:         assert abs(distance)<=self.height, "invalid distance %i for size %i" % (distance, self.height)
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    __pyx_t_2 = __Pyx_PyInt_From_int16_t(__pyx_v_distance); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 288, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_3 = __Pyx_PyNumber_Absolute(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 288, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = __Pyx_PyInt_From_uint16_t(__pyx_v_self->height); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 288, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_4 = PyObject_RichCompare(__pyx_t_3, __pyx_t_2, Py_LE); __Pyx_XGOTREF(__pyx_t_4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 288, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_5 < 0)) __PYX_ERR(0, 288, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (unlikely(!__pyx_t_5)) {
      __pyx_t_4 = __Pyx_PyInt_From_int16_t(__pyx_v_distance); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 288, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_4);
      __pyx_t_2 = __Pyx_PyInt_From_uint16_t(__pyx_v_self->height); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 288, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 288, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_GIVEREF(__pyx_t_4);
      PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_t_4);
      __Pyx_GIVEREF(__pyx_t_2);
      PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_2);
      __pyx_t_4 = 0;
      __pyx_t_2 = 0;
      __pyx_t_2 = __Pyx_PyString_Format(__pyx_kp_s_invalid_distance_i_for_size_i, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 288, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      PyErr_SetObject(PyExc_AssertionError, __pyx_t_2);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __PYX_ERR(0, 288, __pyx_L1_error)
    }
  }
  #endif
+289:         cdef uint16_t rstart = 0
  __pyx_v_rstart = 0;
+290:         cdef uint16_t rend = self.height-distance
  __pyx_v_rend = (__pyx_v_self->height - __pyx_v_distance);
+291:         if distance<0:
  __pyx_t_5 = ((__pyx_v_distance < 0) != 0);
  if (__pyx_t_5) {
/* … */
  }
+292:             rstart = -distance
    __pyx_v_rstart = (-__pyx_v_distance);
+293:             rend = self.height
    __pyx_t_6 = __pyx_v_self->height;
    __pyx_v_rend = __pyx_t_6;
+294:         cdef uint16_t i1, i2, start = 0, count = 0
  __pyx_v_start = 0;
  __pyx_v_count = 0;
+295:         line_defs = collections.OrderedDict()
  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_collections); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 295, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_n_s_OrderedDict); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 295, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_4))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_4, function);
    }
  }
  if (__pyx_t_3) {
    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 295, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  } else {
    __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 295, __pyx_L1_error)
  }
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_v_line_defs = __pyx_t_2;
  __pyx_t_2 = 0;
+296:         for i1 in range(rstart, rend):
  __pyx_t_6 = __pyx_v_rend;
  __pyx_t_7 = __pyx_t_6;
  for (__pyx_t_8 = __pyx_v_rstart; __pyx_t_8 < __pyx_t_7; __pyx_t_8+=1) {
    __pyx_v_i1 = __pyx_t_8;
+297:             i2 = i1+distance
    __pyx_v_i2 = (__pyx_v_i1 + __pyx_v_distance);
+298:             if line_state[i2]:
    __pyx_t_5 = ((__pyx_v_line_state[__pyx_v_i2]) != 0);
    if (__pyx_t_5) {
/* … */
    }
 299:                 #this target line has been marked as matched already
+300:                 continue
      goto __pyx_L4_continue;
 301:             #if DEBUG:
 302:             #    log("%i: a1=%i / a2=%i", i, a1[i], a2[i+distance])
+303:             if a1[i1]==a2[i2]:
    __pyx_t_5 = (((__pyx_v_a1[__pyx_v_i1]) == (__pyx_v_a2[__pyx_v_i2])) != 0);
    if (__pyx_t_5) {
/* … */
      goto __pyx_L7;
    }
 304:                 #if DEBUG:
 305:                 #    log("match at %i: %i", i, a1[i])
+306:                 if count==0:
      __pyx_t_5 = ((__pyx_v_count == 0) != 0);
      if (__pyx_t_5) {
/* … */
      }
+307:                     start = i1
        __pyx_v_start = __pyx_v_i1;
+308:                 count += 1
      __pyx_v_count = (__pyx_v_count + 1);
 309:                 #mark the target line as dealt with:
+310:             elif count>0:
    __pyx_t_5 = ((__pyx_v_count > 0) != 0);
    if (__pyx_t_5) {
/* … */
    }
    __pyx_L7:;
    __pyx_L4_continue:;
  }
 311:                 #we had a match
+312:                 if count>MIN_LINE_COUNT:
      __pyx_t_5 = ((__pyx_v_count > 5) != 0);
      if (__pyx_t_5) {
/* … */
      }
+313:                     line_defs[start] = count
        __pyx_t_2 = __Pyx_PyInt_From_uint16_t(__pyx_v_count); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 313, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        if (unlikely(__Pyx_SetItemInt(__pyx_v_line_defs, __pyx_v_start, __pyx_t_2, uint16_t, 0, __Pyx_PyInt_From_uint16_t, 0, 0, 0) < 0)) __PYX_ERR(0, 313, __pyx_L1_error)
        __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+314:                 count = 0
      __pyx_v_count = 0;
+315:         if count>0:
  __pyx_t_5 = ((__pyx_v_count > 0) != 0);
  if (__pyx_t_5) {
/* … */
  }
 316:             #last few lines ended as a match:
+317:             line_defs[start] = count
    __pyx_t_2 = __Pyx_PyInt_From_uint16_t(__pyx_v_count); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 317, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    if (unlikely(__Pyx_SetItemInt(__pyx_v_line_defs, __pyx_v_start, __pyx_t_2, uint16_t, 0, __Pyx_PyInt_From_uint16_t, 0, 0, 0) < 0)) __PYX_ERR(0, 317, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 318:         #clear the ones we have matched:
+319:         for start, count in line_defs.items():
  __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_line_defs, __pyx_n_s_items); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 319, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_3 = NULL;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_4))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_4);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_4);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_4, function);
    }
  }
  if (__pyx_t_3) {
    __pyx_t_2 = __Pyx_PyObject_CallOneArg(__pyx_t_4, __pyx_t_3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 319, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  } else {
    __pyx_t_2 = __Pyx_PyObject_CallNoArg(__pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 319, __pyx_L1_error)
  }
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (likely(PyList_CheckExact(__pyx_t_2)) || PyTuple_CheckExact(__pyx_t_2)) {
    __pyx_t_4 = __pyx_t_2; __Pyx_INCREF(__pyx_t_4); __pyx_t_9 = 0;
    __pyx_t_10 = NULL;
  } else {
    __pyx_t_9 = -1; __pyx_t_4 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 319, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __pyx_t_10 = Py_TYPE(__pyx_t_4)->tp_iternext; if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 319, __pyx_L1_error)
  }
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  for (;;) {
    if (likely(!__pyx_t_10)) {
      if (likely(PyList_CheckExact(__pyx_t_4))) {
        if (__pyx_t_9 >= PyList_GET_SIZE(__pyx_t_4)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_2 = PyList_GET_ITEM(__pyx_t_4, __pyx_t_9); __Pyx_INCREF(__pyx_t_2); __pyx_t_9++; if (unlikely(0 < 0)) __PYX_ERR(0, 319, __pyx_L1_error)
        #else
        __pyx_t_2 = PySequence_ITEM(__pyx_t_4, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 319, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        #endif
      } else {
        if (__pyx_t_9 >= PyTuple_GET_SIZE(__pyx_t_4)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_2 = PyTuple_GET_ITEM(__pyx_t_4, __pyx_t_9); __Pyx_INCREF(__pyx_t_2); __pyx_t_9++; if (unlikely(0 < 0)) __PYX_ERR(0, 319, __pyx_L1_error)
        #else
        __pyx_t_2 = PySequence_ITEM(__pyx_t_4, __pyx_t_9); __pyx_t_9++; if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 319, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_2);
        #endif
      }
    } else {
      __pyx_t_2 = __pyx_t_10(__pyx_t_4);
      if (unlikely(!__pyx_t_2)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 319, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_2);
    }
    if ((likely(PyTuple_CheckExact(__pyx_t_2))) || (PyList_CheckExact(__pyx_t_2))) {
      PyObject* sequence = __pyx_t_2;
      Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
      if (unlikely(size != 2)) {
        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
        __PYX_ERR(0, 319, __pyx_L1_error)
      }
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      if (likely(PyTuple_CheckExact(sequence))) {
        __pyx_t_3 = PyTuple_GET_ITEM(sequence, 0); 
        __pyx_t_11 = PyTuple_GET_ITEM(sequence, 1); 
      } else {
        __pyx_t_3 = PyList_GET_ITEM(sequence, 0); 
        __pyx_t_11 = PyList_GET_ITEM(sequence, 1); 
      }
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_11);
      #else
      __pyx_t_3 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 319, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_11 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 319, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      #endif
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    } else {
      Py_ssize_t index = -1;
      __pyx_t_12 = PyObject_GetIter(__pyx_t_2); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 319, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_12);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
      __pyx_t_13 = Py_TYPE(__pyx_t_12)->tp_iternext;
      index = 0; __pyx_t_3 = __pyx_t_13(__pyx_t_12); if (unlikely(!__pyx_t_3)) goto __pyx_L13_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_3);
      index = 1; __pyx_t_11 = __pyx_t_13(__pyx_t_12); if (unlikely(!__pyx_t_11)) goto __pyx_L13_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_11);
      if (__Pyx_IternextUnpackEndCheck(__pyx_t_13(__pyx_t_12), 2) < 0) __PYX_ERR(0, 319, __pyx_L1_error)
      __pyx_t_13 = NULL;
      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
      goto __pyx_L14_unpacking_done;
      __pyx_L13_unpacking_failed:;
      __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
      __pyx_t_13 = NULL;
      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
      __PYX_ERR(0, 319, __pyx_L1_error)
      __pyx_L14_unpacking_done:;
    }
    __pyx_t_6 = __Pyx_PyInt_As_uint16_t(__pyx_t_3); if (unlikely((__pyx_t_6 == ((uint16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 319, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_t_7 = __Pyx_PyInt_As_uint16_t(__pyx_t_11); if (unlikely((__pyx_t_7 == ((uint16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 319, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
    __pyx_v_start = __pyx_t_6;
    __pyx_v_count = __pyx_t_7;
/* … */
  }
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
+320:             for i in range(count):
    __pyx_t_2 = __Pyx_PyInt_From_uint16_t(__pyx_v_count); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 320, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_11 = __Pyx_PyObject_CallOneArg(__pyx_builtin_range, __pyx_t_2); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 320, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_11);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    if (likely(PyList_CheckExact(__pyx_t_11)) || PyTuple_CheckExact(__pyx_t_11)) {
      __pyx_t_2 = __pyx_t_11; __Pyx_INCREF(__pyx_t_2); __pyx_t_14 = 0;
      __pyx_t_15 = NULL;
    } else {
      __pyx_t_14 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_11); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 320, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_15 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_15)) __PYX_ERR(0, 320, __pyx_L1_error)
    }
    __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
    for (;;) {
      if (likely(!__pyx_t_15)) {
        if (likely(PyList_CheckExact(__pyx_t_2))) {
          if (__pyx_t_14 >= PyList_GET_SIZE(__pyx_t_2)) break;
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_11 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_14); __Pyx_INCREF(__pyx_t_11); __pyx_t_14++; if (unlikely(0 < 0)) __PYX_ERR(0, 320, __pyx_L1_error)
          #else
          __pyx_t_11 = PySequence_ITEM(__pyx_t_2, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 320, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_11);
          #endif
        } else {
          if (__pyx_t_14 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_11 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_14); __Pyx_INCREF(__pyx_t_11); __pyx_t_14++; if (unlikely(0 < 0)) __PYX_ERR(0, 320, __pyx_L1_error)
          #else
          __pyx_t_11 = PySequence_ITEM(__pyx_t_2, __pyx_t_14); __pyx_t_14++; if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 320, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_11);
          #endif
        }
      } else {
        __pyx_t_11 = __pyx_t_15(__pyx_t_2);
        if (unlikely(!__pyx_t_11)) {
          PyObject* exc_type = PyErr_Occurred();
          if (exc_type) {
            if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
            else __PYX_ERR(0, 320, __pyx_L1_error)
          }
          break;
        }
        __Pyx_GOTREF(__pyx_t_11);
      }
      __Pyx_XDECREF_SET(__pyx_v_i, __pyx_t_11);
      __pyx_t_11 = 0;
/* … */
    }
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+321:                 line_state[start+distance+i] = 1
      __pyx_t_11 = __Pyx_PyInt_From_int((__pyx_v_start + __pyx_v_distance)); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 321, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_11);
      __pyx_t_3 = PyNumber_Add(__pyx_t_11, __pyx_v_i); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 321, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_3);
      __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0;
      __pyx_t_16 = __Pyx_PyIndex_AsSsize_t(__pyx_t_3); if (unlikely((__pyx_t_16 == (Py_ssize_t)-1) && PyErr_Occurred())) __PYX_ERR(0, 321, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
      (__pyx_v_line_state[__pyx_t_16]) = 1;
 322:         #if DEBUG:
 323:         #    log("match_distance(%i)=%s", distance, line_defs)
+324:         return line_defs
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_v_line_defs);
  __pyx_r = __pyx_v_line_defs;
  goto __pyx_L0;
 325: 
 326: 
+327:     def invalidate(self, int16_t x, int16_t y, int16_t w, int16_t h):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_13invalidate(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_13invalidate(PyObject *__pyx_v_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  int16_t __pyx_v_x;
  int16_t __pyx_v_y;
  int16_t __pyx_v_w;
  int16_t __pyx_v_h;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("invalidate (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_x,&__pyx_n_s_y,&__pyx_n_s_w,&__pyx_n_s_h,0};
    PyObject* values[4] = {0,0,0,0};
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  4: values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
        CYTHON_FALLTHROUGH;
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_x)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_y)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("invalidate", 1, 4, 4, 1); __PYX_ERR(0, 327, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_w)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("invalidate", 1, 4, 4, 2); __PYX_ERR(0, 327, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  3:
        if (likely((values[3] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_h)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("invalidate", 1, 4, 4, 3); __PYX_ERR(0, 327, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "invalidate") < 0)) __PYX_ERR(0, 327, __pyx_L3_error)
      }
    } else if (PyTuple_GET_SIZE(__pyx_args) != 4) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
      values[3] = PyTuple_GET_ITEM(__pyx_args, 3);
    }
    __pyx_v_x = __Pyx_PyInt_As_int16_t(values[0]); if (unlikely((__pyx_v_x == ((int16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 327, __pyx_L3_error)
    __pyx_v_y = __Pyx_PyInt_As_int16_t(values[1]); if (unlikely((__pyx_v_y == ((int16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 327, __pyx_L3_error)
    __pyx_v_w = __Pyx_PyInt_As_int16_t(values[2]); if (unlikely((__pyx_v_w == ((int16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 327, __pyx_L3_error)
    __pyx_v_h = __Pyx_PyInt_As_int16_t(values[3]); if (unlikely((__pyx_v_h == ((int16_t)-1)) && PyErr_Occurred())) __PYX_ERR(0, 327, __pyx_L3_error)
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("invalidate", 1, 4, 4, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 327, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("xpra.server.window.motion.ScrollData.invalidate", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_4xpra_6server_6window_6motion_10ScrollData_12invalidate(((struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *)__pyx_v_self), __pyx_v_x, __pyx_v_y, __pyx_v_w, __pyx_v_h);

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_6window_6motion_10ScrollData_12invalidate(struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *__pyx_v_self, int16_t __pyx_v_x, int16_t __pyx_v_y, int16_t __pyx_v_w, int16_t __pyx_v_h) {
  PyObject *__pyx_v_rect = NULL;
  PyObject *__pyx_v_inter = NULL;
  int __pyx_v_start_y;
  int __pyx_v_i;
  uint16_t __pyx_v_nonzero;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("invalidate", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_XDECREF(__pyx_t_10);
  __Pyx_AddTraceback("xpra.server.window.motion.ScrollData.invalidate", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_rect);
  __Pyx_XDECREF(__pyx_v_inter);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
+328:         if self.a2==NULL:
  __pyx_t_1 = ((__pyx_v_self->a2 == NULL) != 0);
  if (__pyx_t_1) {
/* … */
  }
 329:             #nothing to invalidate!
+330:             return
    __Pyx_XDECREF(__pyx_r);
    __pyx_r = Py_None; __Pyx_INCREF(Py_None);
    goto __pyx_L0;
 331:         #do they intersect?
+332:         rect = rectangle(self.x, self.y, self.width, self.height)
  __pyx_t_3 = __Pyx_GetModuleGlobalName(__pyx_n_s_rectangle); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 332, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = __Pyx_PyInt_From_uint16_t(__pyx_v_self->x); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 332, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_5 = __Pyx_PyInt_From_uint16_t(__pyx_v_self->y); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 332, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_6 = __Pyx_PyInt_From_uint16_t(__pyx_v_self->width); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 332, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_7 = __Pyx_PyInt_From_uint16_t(__pyx_v_self->height); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 332, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __pyx_t_8 = NULL;
  __pyx_t_9 = 0;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_8 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_8)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_8);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
      __pyx_t_9 = 1;
    }
  }
  #if CYTHON_FAST_PYCALL
  if (PyFunction_Check(__pyx_t_3)) {
    PyObject *__pyx_temp[5] = {__pyx_t_8, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7};
    __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 4+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 332, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  } else
  #endif
  #if CYTHON_FAST_PYCCALL
  if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
    PyObject *__pyx_temp[5] = {__pyx_t_8, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7};
    __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 4+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 332, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0;
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
  } else
  #endif
  {
    __pyx_t_10 = PyTuple_New(4+__pyx_t_9); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 332, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_10);
    if (__pyx_t_8) {
      __Pyx_GIVEREF(__pyx_t_8); PyTuple_SET_ITEM(__pyx_t_10, 0, __pyx_t_8); __pyx_t_8 = NULL;
    }
    __Pyx_GIVEREF(__pyx_t_4);
    PyTuple_SET_ITEM(__pyx_t_10, 0+__pyx_t_9, __pyx_t_4);
    __Pyx_GIVEREF(__pyx_t_5);
    PyTuple_SET_ITEM(__pyx_t_10, 1+__pyx_t_9, __pyx_t_5);
    __Pyx_GIVEREF(__pyx_t_6);
    PyTuple_SET_ITEM(__pyx_t_10, 2+__pyx_t_9, __pyx_t_6);
    __Pyx_GIVEREF(__pyx_t_7);
    PyTuple_SET_ITEM(__pyx_t_10, 3+__pyx_t_9, __pyx_t_7);
    __pyx_t_4 = 0;
    __pyx_t_5 = 0;
    __pyx_t_6 = 0;
    __pyx_t_7 = 0;
    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_10, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 332, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
  }
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_rect = __pyx_t_2;
  __pyx_t_2 = 0;
+333:         inter = rect.intersection(x, y, w, h)
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_rect, __pyx_n_s_intersection); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 333, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_10 = __Pyx_PyInt_From_int16_t(__pyx_v_x); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 333, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_10);
  __pyx_t_7 = __Pyx_PyInt_From_int16_t(__pyx_v_y); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 333, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __pyx_t_6 = __Pyx_PyInt_From_int16_t(__pyx_v_w); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 333, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_5 = __Pyx_PyInt_From_int16_t(__pyx_v_h); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 333, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_4 = NULL;
  __pyx_t_9 = 0;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_4)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_4);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
      __pyx_t_9 = 1;
    }
  }
  #if CYTHON_FAST_PYCALL
  if (PyFunction_Check(__pyx_t_3)) {
    PyObject *__pyx_temp[5] = {__pyx_t_4, __pyx_t_10, __pyx_t_7, __pyx_t_6, __pyx_t_5};
    __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 4+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 333, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  } else
  #endif
  #if CYTHON_FAST_PYCCALL
  if (__Pyx_PyFastCFunction_Check(__pyx_t_3)) {
    PyObject *__pyx_temp[5] = {__pyx_t_4, __pyx_t_10, __pyx_t_7, __pyx_t_6, __pyx_t_5};
    __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_3, __pyx_temp+1-__pyx_t_9, 4+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 333, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
    __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0;
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  } else
  #endif
  {
    __pyx_t_8 = PyTuple_New(4+__pyx_t_9); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 333, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    if (__pyx_t_4) {
      __Pyx_GIVEREF(__pyx_t_4); PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_4); __pyx_t_4 = NULL;
    }
    __Pyx_GIVEREF(__pyx_t_10);
    PyTuple_SET_ITEM(__pyx_t_8, 0+__pyx_t_9, __pyx_t_10);
    __Pyx_GIVEREF(__pyx_t_7);
    PyTuple_SET_ITEM(__pyx_t_8, 1+__pyx_t_9, __pyx_t_7);
    __Pyx_GIVEREF(__pyx_t_6);
    PyTuple_SET_ITEM(__pyx_t_8, 2+__pyx_t_9, __pyx_t_6);
    __Pyx_GIVEREF(__pyx_t_5);
    PyTuple_SET_ITEM(__pyx_t_8, 3+__pyx_t_9, __pyx_t_5);
    __pyx_t_10 = 0;
    __pyx_t_7 = 0;
    __pyx_t_6 = 0;
    __pyx_t_5 = 0;
    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_8, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 333, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
  }
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_v_inter = __pyx_t_2;
  __pyx_t_2 = 0;
+334:         if not inter:
  __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_v_inter); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 334, __pyx_L1_error)
  __pyx_t_11 = ((!__pyx_t_1) != 0);
  if (__pyx_t_11) {
/* … */
  }
+335:             return
    __Pyx_XDECREF(__pyx_r);
    __pyx_r = Py_None; __Pyx_INCREF(Py_None);
    goto __pyx_L0;
 336:         #remove any lines that have been updated
 337:         #by zeroing out their checksums:
+338:         assert inter.height<=self.height
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_inter, __pyx_n_s_height); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 338, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_3 = __Pyx_PyInt_From_uint16_t(__pyx_v_self->height); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 338, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_8 = PyObject_RichCompare(__pyx_t_2, __pyx_t_3, Py_LE); __Pyx_XGOTREF(__pyx_t_8); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 338, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_t_8); if (unlikely(__pyx_t_11 < 0)) __PYX_ERR(0, 338, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    if (unlikely(!__pyx_t_11)) {
      PyErr_SetNone(PyExc_AssertionError);
      __PYX_ERR(0, 338, __pyx_L1_error)
    }
  }
  #endif
+339:         assert inter.y>=rect.y and inter.y+inter.height<=rect.y+rect.height
  #ifndef CYTHON_WITHOUT_ASSERTIONS
  if (unlikely(!Py_OptimizeFlag)) {
    __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_inter, __pyx_n_s_y); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 339, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_rect, __pyx_n_s_y); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 339, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_2 = PyObject_RichCompare(__pyx_t_8, __pyx_t_3, Py_GE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 339, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 339, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    if (__pyx_t_1) {
    } else {
      __pyx_t_11 = __pyx_t_1;
      goto __pyx_L5_bool_binop_done;
    }
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_inter, __pyx_n_s_y); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 339, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_inter, __pyx_n_s_height); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 339, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_8 = PyNumber_Add(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 339, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_8);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_rect, __pyx_n_s_y); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 339, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_rect, __pyx_n_s_height); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 339, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_5 = PyNumber_Add(__pyx_t_3, __pyx_t_2); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 339, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_2 = PyObject_RichCompare(__pyx_t_8, __pyx_t_5, Py_LE); __Pyx_XGOTREF(__pyx_t_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 339, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
    __pyx_t_1 = __Pyx_PyObject_IsTrue(__pyx_t_2); if (unlikely(__pyx_t_1 < 0)) __PYX_ERR(0, 339, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __pyx_t_11 = __pyx_t_1;
    __pyx_L5_bool_binop_done:;
    if (unlikely(!__pyx_t_11)) {
      PyErr_SetNone(PyExc_AssertionError);
      __PYX_ERR(0, 339, __pyx_L1_error)
    }
  }
  #endif
 340:         #the array indexes are relative to rect.y:
+341:         cdef int start_y = inter.y-rect.y
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_inter, __pyx_n_s_y); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 341, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_rect, __pyx_n_s_y); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 341, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_8 = PyNumber_Subtract(__pyx_t_2, __pyx_t_5); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 341, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_8);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_9 = __Pyx_PyInt_As_int(__pyx_t_8); if (unlikely((__pyx_t_9 == (int)-1) && PyErr_Occurred())) __PYX_ERR(0, 341, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
  __pyx_v_start_y = __pyx_t_9;
 342:         cdef int i
+343:         for i in range(start_y, start_y+inter.height):
  __pyx_t_8 = __Pyx_PyInt_From_int(__pyx_v_start_y); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 343, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_8);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_inter, __pyx_n_s_height); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 343, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_2 = PyNumber_Add(__pyx_t_8, __pyx_t_5); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 343, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_12 = __Pyx_PyInt_As_long(__pyx_t_2); if (unlikely((__pyx_t_12 == (long)-1) && PyErr_Occurred())) __PYX_ERR(0, 343, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_13 = __pyx_t_12;
  for (__pyx_t_9 = __pyx_v_start_y; __pyx_t_9 < __pyx_t_13; __pyx_t_9+=1) {
    __pyx_v_i = __pyx_t_9;
+344:             self.a2[i] = 0
    (__pyx_v_self->a2[__pyx_v_i]) = 0;
  }
+345:         cdef uint16_t nonzero = 0
  __pyx_v_nonzero = 0;
+346:         for i in range(self.height):
  __pyx_t_14 = __pyx_v_self->height;
  __pyx_t_15 = __pyx_t_14;
  for (__pyx_t_9 = 0; __pyx_t_9 < __pyx_t_15; __pyx_t_9+=1) {
    __pyx_v_i = __pyx_t_9;
+347:             if self.a2[i]!=0:
    __pyx_t_11 = (((__pyx_v_self->a2[__pyx_v_i]) != 0) != 0);
    if (__pyx_t_11) {
/* … */
    }
  }
+348:                 nonzero += 1
      __pyx_v_nonzero = (__pyx_v_nonzero + 1);
+349:         log("invalidated %i lines checksums from intersection of scroll area %s and rectangle %s, remains %i", inter.height, rect, (x, y, w, h), nonzero)
  __pyx_t_5 = __Pyx_GetModuleGlobalName(__pyx_n_s_log); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_inter, __pyx_n_s_height); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_8);
  __pyx_t_3 = __Pyx_PyInt_From_int16_t(__pyx_v_x); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_6 = __Pyx_PyInt_From_int16_t(__pyx_v_y); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_7 = __Pyx_PyInt_From_int16_t(__pyx_v_w); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __pyx_t_10 = __Pyx_PyInt_From_int16_t(__pyx_v_h); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_10);
  __pyx_t_4 = PyTuple_New(4); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_3);
  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_3);
  __Pyx_GIVEREF(__pyx_t_6);
  PyTuple_SET_ITEM(__pyx_t_4, 1, __pyx_t_6);
  __Pyx_GIVEREF(__pyx_t_7);
  PyTuple_SET_ITEM(__pyx_t_4, 2, __pyx_t_7);
  __Pyx_GIVEREF(__pyx_t_10);
  PyTuple_SET_ITEM(__pyx_t_4, 3, __pyx_t_10);
  __pyx_t_3 = 0;
  __pyx_t_6 = 0;
  __pyx_t_7 = 0;
  __pyx_t_10 = 0;
  __pyx_t_10 = __Pyx_PyInt_From_uint16_t(__pyx_v_nonzero); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 349, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_10);
  __pyx_t_7 = NULL;
  __pyx_t_9 = 0;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_5))) {
    __pyx_t_7 = PyMethod_GET_SELF(__pyx_t_5);
    if (likely(__pyx_t_7)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_7);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_5, function);
      __pyx_t_9 = 1;
    }
  }
  #if CYTHON_FAST_PYCALL
  if (PyFunction_Check(__pyx_t_5)) {
    PyObject *__pyx_temp[6] = {__pyx_t_7, __pyx_kp_s_invalidated_i_lines_checksums_fr, __pyx_t_8, __pyx_v_rect, __pyx_t_4, __pyx_t_10};
    __pyx_t_2 = __Pyx_PyFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_9, 5+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 349, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
  } else
  #endif
  #if CYTHON_FAST_PYCCALL
  if (__Pyx_PyFastCFunction_Check(__pyx_t_5)) {
    PyObject *__pyx_temp[6] = {__pyx_t_7, __pyx_kp_s_invalidated_i_lines_checksums_fr, __pyx_t_8, __pyx_v_rect, __pyx_t_4, __pyx_t_10};
    __pyx_t_2 = __Pyx_PyCFunction_FastCall(__pyx_t_5, __pyx_temp+1-__pyx_t_9, 5+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 349, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0;
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
  } else
  #endif
  {
    __pyx_t_6 = PyTuple_New(5+__pyx_t_9); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 349, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    if (__pyx_t_7) {
      __Pyx_GIVEREF(__pyx_t_7); PyTuple_SET_ITEM(__pyx_t_6, 0, __pyx_t_7); __pyx_t_7 = NULL;
    }
    __Pyx_INCREF(__pyx_kp_s_invalidated_i_lines_checksums_fr);
    __Pyx_GIVEREF(__pyx_kp_s_invalidated_i_lines_checksums_fr);
    PyTuple_SET_ITEM(__pyx_t_6, 0+__pyx_t_9, __pyx_kp_s_invalidated_i_lines_checksums_fr);
    __Pyx_GIVEREF(__pyx_t_8);
    PyTuple_SET_ITEM(__pyx_t_6, 1+__pyx_t_9, __pyx_t_8);
    __Pyx_INCREF(__pyx_v_rect);
    __Pyx_GIVEREF(__pyx_v_rect);
    PyTuple_SET_ITEM(__pyx_t_6, 2+__pyx_t_9, __pyx_v_rect);
    __Pyx_GIVEREF(__pyx_t_4);
    PyTuple_SET_ITEM(__pyx_t_6, 3+__pyx_t_9, __pyx_t_4);
    __Pyx_GIVEREF(__pyx_t_10);
    PyTuple_SET_ITEM(__pyx_t_6, 4+__pyx_t_9, __pyx_t_10);
    __pyx_t_8 = 0;
    __pyx_t_4 = 0;
    __pyx_t_10 = 0;
    __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_5, __pyx_t_6, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 349, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  }
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 350:         #if more than half has already been invalidated, drop it completely:
+351:         if nonzero<=rect.height//2:
  __pyx_t_2 = __Pyx_PyInt_From_uint16_t(__pyx_v_nonzero); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 351, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_rect, __pyx_n_s_height); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 351, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_5);
  __pyx_t_6 = __Pyx_PyInt_FloorDivideObjC(__pyx_t_5, __pyx_int_2, 2, 0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 351, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  __pyx_t_5 = PyObject_RichCompare(__pyx_t_2, __pyx_t_6, Py_LE); __Pyx_XGOTREF(__pyx_t_5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 351, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
  __pyx_t_11 = __Pyx_PyObject_IsTrue(__pyx_t_5); if (unlikely(__pyx_t_11 < 0)) __PYX_ERR(0, 351, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  if (__pyx_t_11) {
/* … */
  }
+352:             log("invalidating whole scroll data as only %i of it remains valid", 100*nonzero//rect.height)
    __pyx_t_6 = __Pyx_GetModuleGlobalName(__pyx_n_s_log); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 352, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __pyx_t_2 = __Pyx_PyInt_From_long((0x64 * __pyx_v_nonzero)); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 352, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_rect, __pyx_n_s_height); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 352, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_10);
    __pyx_t_4 = PyNumber_FloorDivide(__pyx_t_2, __pyx_t_10); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 352, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0;
    __pyx_t_10 = NULL;
    __pyx_t_9 = 0;
    if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) {
      __pyx_t_10 = PyMethod_GET_SELF(__pyx_t_6);
      if (likely(__pyx_t_10)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6);
        __Pyx_INCREF(__pyx_t_10);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_6, function);
        __pyx_t_9 = 1;
      }
    }
    #if CYTHON_FAST_PYCALL
    if (PyFunction_Check(__pyx_t_6)) {
      PyObject *__pyx_temp[3] = {__pyx_t_10, __pyx_kp_s_invalidating_whole_scroll_data_a, __pyx_t_4};
      __pyx_t_5 = __Pyx_PyFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 352, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    } else
    #endif
    #if CYTHON_FAST_PYCCALL
    if (__Pyx_PyFastCFunction_Check(__pyx_t_6)) {
      PyObject *__pyx_temp[3] = {__pyx_t_10, __pyx_kp_s_invalidating_whole_scroll_data_a, __pyx_t_4};
      __pyx_t_5 = __Pyx_PyCFunction_FastCall(__pyx_t_6, __pyx_temp+1-__pyx_t_9, 2+__pyx_t_9); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 352, __pyx_L1_error)
      __Pyx_XDECREF(__pyx_t_10); __pyx_t_10 = 0;
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    } else
    #endif
    {
      __pyx_t_2 = PyTuple_New(2+__pyx_t_9); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 352, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      if (__pyx_t_10) {
        __Pyx_GIVEREF(__pyx_t_10); PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_10); __pyx_t_10 = NULL;
      }
      __Pyx_INCREF(__pyx_kp_s_invalidating_whole_scroll_data_a);
      __Pyx_GIVEREF(__pyx_kp_s_invalidating_whole_scroll_data_a);
      PyTuple_SET_ITEM(__pyx_t_2, 0+__pyx_t_9, __pyx_kp_s_invalidating_whole_scroll_data_a);
      __Pyx_GIVEREF(__pyx_t_4);
      PyTuple_SET_ITEM(__pyx_t_2, 1+__pyx_t_9, __pyx_t_4);
      __pyx_t_4 = 0;
      __pyx_t_5 = __Pyx_PyObject_Call(__pyx_t_6, __pyx_t_2, NULL); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 352, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    }
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
+353:             free(self.a2)
    free(__pyx_v_self->a2);
+354:             self.a2 = NULL
    __pyx_v_self->a2 = NULL;
 355: 
 356: 
+357:     def get_best_match(self):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_15get_best_match(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_15get_best_match(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("get_best_match (wrapper)", 0);
  __pyx_r = __pyx_pf_4xpra_6server_6window_6motion_10ScrollData_14get_best_match(((struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *)__pyx_v_self));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_6window_6motion_10ScrollData_14get_best_match(struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *__pyx_v_self) {
  int16_t __pyx_v_max_hits;
  int __pyx_v_d;
  unsigned int __pyx_v_i;
  uint16_t __pyx_v_r;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("get_best_match", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_7);
  __Pyx_XDECREF(__pyx_t_8);
  __Pyx_AddTraceback("xpra.server.window.motion.ScrollData.get_best_match", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
+358:         if self.a1==NULL or self.a2==NULL:
  __pyx_t_2 = ((__pyx_v_self->a1 == NULL) != 0);
  if (!__pyx_t_2) {
  } else {
    __pyx_t_1 = __pyx_t_2;
    goto __pyx_L4_bool_binop_done;
  }
  __pyx_t_2 = ((__pyx_v_self->a2 == NULL) != 0);
  __pyx_t_1 = __pyx_t_2;
  __pyx_L4_bool_binop_done:;
  if (__pyx_t_1) {
/* … */
  }
+359:             return 0, 0
    __Pyx_XDECREF(__pyx_r);
    __Pyx_INCREF(__pyx_tuple__3);
    __pyx_r = __pyx_tuple__3;
    goto __pyx_L0;
/* … */
  __pyx_tuple__3 = PyTuple_Pack(2, __pyx_int_0, __pyx_int_0); if (unlikely(!__pyx_tuple__3)) __PYX_ERR(0, 359, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__3);
  __Pyx_GIVEREF(__pyx_tuple__3);
+360:         cdef int16_t max_hits = 0
  __pyx_v_max_hits = 0;
+361:         cdef int d = 0
  __pyx_v_d = 0;
 362:         cdef unsigned int i
+363:         cdef uint16_t r = 2*self.height
  __pyx_v_r = (2 * __pyx_v_self->height);
+364:         for i in range(r):
  __pyx_t_3 = __pyx_v_r;
  __pyx_t_4 = __pyx_t_3;
  for (__pyx_t_5 = 0; __pyx_t_5 < __pyx_t_4; __pyx_t_5+=1) {
    __pyx_v_i = __pyx_t_5;
+365:             if self.distances[i]>max_hits:
    __pyx_t_1 = (((__pyx_v_self->distances[__pyx_v_i]) > __pyx_v_max_hits) != 0);
    if (__pyx_t_1) {
/* … */
    }
  }
+366:                 max_hits = self.distances[i]
      __pyx_v_max_hits = (__pyx_v_self->distances[__pyx_v_i]);
+367:                 d = i-self.height
      __pyx_v_d = (__pyx_v_i - __pyx_v_self->height);
+368:         return d, max_hits
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_6 = __Pyx_PyInt_From_int(__pyx_v_d); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 368, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_6);
  __pyx_t_7 = __Pyx_PyInt_From_int16_t(__pyx_v_max_hits); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 368, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_7);
  __pyx_t_8 = PyTuple_New(2); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 368, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_8);
  __Pyx_GIVEREF(__pyx_t_6);
  PyTuple_SET_ITEM(__pyx_t_8, 0, __pyx_t_6);
  __Pyx_GIVEREF(__pyx_t_7);
  PyTuple_SET_ITEM(__pyx_t_8, 1, __pyx_t_7);
  __pyx_t_6 = 0;
  __pyx_t_7 = 0;
  __pyx_r = __pyx_t_8;
  __pyx_t_8 = 0;
  goto __pyx_L0;
 369: 
+370:     def __dealloc__(self):
/* Python wrapper */
static void __pyx_pw_4xpra_6server_6window_6motion_10ScrollData_17__dealloc__(PyObject *__pyx_v_self); /*proto*/
static void __pyx_pw_4xpra_6server_6window_6motion_10ScrollData_17__dealloc__(PyObject *__pyx_v_self) {
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__dealloc__ (wrapper)", 0);
  __pyx_pf_4xpra_6server_6window_6motion_10ScrollData_16__dealloc__(((struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *)__pyx_v_self));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
}

static void __pyx_pf_4xpra_6server_6window_6motion_10ScrollData_16__dealloc__(struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *__pyx_v_self) {
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("__dealloc__", 0);
/* … */
  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_WriteUnraisable("xpra.server.window.motion.ScrollData.__dealloc__", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0);
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
}
+371:         self.free()
  __pyx_t_2 = __Pyx_PyObject_GetAttrStr(((PyObject *)__pyx_v_self), __pyx_n_s_free); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 371, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = NULL;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_2, function);
    }
  }
  if (__pyx_t_3) {
    __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 371, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  } else {
    __pyx_t_1 = __Pyx_PyObject_CallNoArg(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 371, __pyx_L1_error)
  }
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
 372: 
+373:     def free(self):
/* Python wrapper */
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_19free(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused); /*proto*/
static PyObject *__pyx_pw_4xpra_6server_6window_6motion_10ScrollData_19free(PyObject *__pyx_v_self, CYTHON_UNUSED PyObject *unused) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("free (wrapper)", 0);
  __pyx_r = __pyx_pf_4xpra_6server_6window_6motion_10ScrollData_18free(((struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *)__pyx_v_self));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_4xpra_6server_6window_6motion_10ScrollData_18free(struct __pyx_obj_4xpra_6server_6window_6motion_ScrollData *__pyx_v_self) {
  void *__pyx_v_ptr;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("free", 0);
/* … */
  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
+374:         cdef void* ptr = <void*> self.distances
  __pyx_v_ptr = ((void *)__pyx_v_self->distances);
+375:         if ptr:
  __pyx_t_1 = (__pyx_v_ptr != 0);
  if (__pyx_t_1) {
/* … */
  }
+376:             self.distances = NULL
    __pyx_v_self->distances = NULL;
+377:             free(ptr)
    free(__pyx_v_ptr);
+378:         ptr = <void*> self.a1
  __pyx_v_ptr = ((void *)__pyx_v_self->a1);
+379:         if ptr:
  __pyx_t_1 = (__pyx_v_ptr != 0);
  if (__pyx_t_1) {
/* … */
  }
+380:             self.a1 = NULL
    __pyx_v_self->a1 = NULL;
+381:             free(ptr)
    free(__pyx_v_ptr);
+382:         ptr = <void*> self.a2
  __pyx_v_ptr = ((void *)__pyx_v_self->a2);
+383:         if ptr:
  __pyx_t_1 = (__pyx_v_ptr != 0);
  if (__pyx_t_1) {
/* … */
  }
+384:             self.a2 = NULL
    __pyx_v_self->a2 = NULL;
+385:             free(ptr)
    free(__pyx_v_ptr);