Remove dependency on xcursorgen (#3)

This commit is contained in:
Guanzhong Chen 2020-10-04 02:30:00 -04:00 committed by GitHub
parent 5c25adc445
commit ec5eb36902
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 48 deletions

View file

@ -21,7 +21,7 @@ jobs:
python -m pip install --upgrade pip python -m pip install --upgrade pip
pip install flake8 flake8-import-order mypy wheel coverage pip install flake8 flake8-import-order mypy wheel coverage
pip install -r requirements.txt pip install -r requirements.txt
sudo apt-get install x11-apps dmz-cursor-theme sudo apt-get install dmz-cursor-theme
- name: Lint with flake8 - name: Lint with flake8
run: flake8 . run: flake8 .
- name: Typecheck with mypy - name: Typecheck with mypy

View file

@ -10,7 +10,6 @@ from typing import BinaryIO
from win2xcur import shadow from win2xcur import shadow
from win2xcur.parser import open_blob from win2xcur.parser import open_blob
from win2xcur.writer import to_x11 from win2xcur.writer import to_x11
from win2xcur.writer.x11 import check_xcursorgen
def main() -> None: def main() -> None:
@ -37,8 +36,6 @@ def main() -> None:
args = parser.parse_args() args = parser.parse_args()
print_lock = Lock() print_lock = Lock()
check_xcursorgen()
def process(file: BinaryIO) -> None: def process(file: BinaryIO) -> None:
name = file.name name = file.name
blob = file.read() blob = file.read()

View file

@ -1,54 +1,49 @@
import os from itertools import chain
import subprocess from operator import itemgetter
import sys
from tempfile import TemporaryDirectory
from typing import List from typing import List
from wand.image import Image
from win2xcur.cursor import CursorFrame from win2xcur.cursor import CursorFrame
from win2xcur.parser import XCursorParser
xcursorgen_checked = False
def check_xcursorgen() -> None:
global xcursorgen_checked
if xcursorgen_checked:
return
try:
subprocess.check_call(['xcursorgen', '--version'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
except subprocess.CalledProcessError:
raise RuntimeError('xcursorgen must be installed to create X11 cursors!')
else:
xcursorgen_checked = True
def to_x11(frames: List[CursorFrame]) -> bytes: def to_x11(frames: List[CursorFrame]) -> bytes:
check_xcursorgen() chunks = []
counter = 0
configs = []
with TemporaryDirectory() as png_dir:
for frame in frames: for frame in frames:
for cursor in frame: for cursor in frame:
name = '%d.png' % (counter,)
hx, hy = cursor.hotspot hx, hy = cursor.hotspot
configs.append('%d %d %d %s %d' % (cursor.image.width, hx, hy, name, int(frame.delay * 1000))) header = XCursorParser.IMAGE_HEADER.pack(
XCursorParser.IMAGE_HEADER.size,
XCursorParser.CHUNK_IMAGE,
cursor.image.width,
1,
cursor.image.width,
cursor.image.height,
hx,
hy,
int(frame.delay * 1000),
)
chunks.append((
XCursorParser.CHUNK_IMAGE,
cursor.image.width,
header + bytes(cursor.image.export_pixels(channel_map='BGRA'))
))
image = Image(image=cursor.image) header = XCursorParser.FILE_HEADER.pack(
image.save(filename=os.path.join(png_dir, name)) XCursorParser.MAGIC,
counter += 1 XCursorParser.FILE_HEADER.size,
XCursorParser.VERSION,
len(chunks),
)
output_file = os.path.join(png_dir, 'cursor') offset = XCursorParser.FILE_HEADER.size + len(chunks) * XCursorParser.TOC_CHUNK.size
process = subprocess.Popen(['xcursorgen', '-p', png_dir, '-', output_file], stdin=subprocess.PIPE, toc = []
stderr=subprocess.PIPE) for chunk_type, chunk_subtype, chunk in chunks:
toc.append(XCursorParser.TOC_CHUNK.pack(
chunk_type,
chunk_subtype,
offset,
))
offset += len(chunk)
_, error = process.communicate('\n'.join(configs).encode(sys.getfilesystemencoding())) return b''.join(chain([header], toc, map(itemgetter(2), chunks)))
if process.wait() != 0:
raise RuntimeError('xcursorgen failed: %r' % error)
with open(output_file, 'rb') as f:
result = f.read()
return result