#!/opt/thinlinc/libexec/python3
# -*- mode: python; coding: utf-8 -*-
#
# Copyright 2022 Linn Mattsson for Cendio AB
# For more information, see http://www.cendio.com
if 82 - 82: Iii1i
import os
import sys
import time
import signal
if 87 - 87: Ii % i1i1i1111I . Oo / OooOoo * I1Ii1I1 - I1I
try :
 import cairo
except ImportError :
 cairo = None
 if 81 - 81: i1 + ooOOO / oOo0O00 * i1iiIII111 * IiIIii11Ii
try :
 from cairo import Error as CairoError
except ImportError :
 if 84 - 84: ooo000 - Ooo0Ooo + iI1iII1I1I1i . IIiIIiIi11I1
 CairoError = Exception
 if 98 - 98: I11iiIi11i1I % oOO
from thinlinc . optionparse import OptionParser
from thinlinc . Xlib import display , X
from thinlinc . Xlib . ext import randr
from thinlinc . Xlib . error import DisplayConnectionError
from thinlinc . Xlib . protocol import request
if 31 - 31: i1I
def i1I1 ( * args ) :
 I1Ii111i1I = "%s: error:" % os . path . basename ( sys . argv [ 0 ] )
 print ( I1Ii111i1I , * args , file = sys . stderr )
 if 52 - 52: OOooooOo00 * i1I / Iii1i / Ii . i1i1i1111I / Ii
def ooO0Oo0o00 ( * args ) :
 I1Ii111i1I = "%s: warning:" % os . path . basename ( sys . argv [ 0 ] )
 print ( I1Ii111i1I , * args , file = sys . stderr )
 if 74 - 74: IIiIIiIi11I1 / I1I - Oo . Ooo0Ooo
def OO0o000o ( color_string_full , default = "#000000" ) :
 def IIiiii1IiIiII ( ) :
  ooO0Oo0o00 ( "Invalid color hex value %s, using default color %s" % ( color_string_full , default ) )
  if 32 - 32: iI1iII1I1I1i
  return OO0o000o ( default )
  if 71 - 71: Ii
 iiIII = color_string_full . lstrip ( '#' )
 if 28 - 28: I1Ii1I1 . Iii1i - ooOOO - iI1iII1I1I1i
 if len ( iiIII ) != 6 :
  return IIiiii1IiIiII ( )
  if 37 - 37: oOO * IIiIIiIi11I1 * I1I / oOo0O00
 i11i1Iii1I1 = { }
 try :
  if 68 - 68: I11iiIi11i1I . i1i1i1111I
  i11i1Iii1I1 [ "red" ] = int ( iiIII [ 0 : 2 ] , 16 )
  i11i1Iii1I1 [ "green" ] = int ( iiIII [ 2 : 4 ] , 16 )
  i11i1Iii1I1 [ "blue" ] = int ( iiIII [ 4 : ] , 16 )
  if 24 - 24: OOooooOo00
 except ValueError as ii1i11i1 :
  return IIiiii1IiIiII ( )
  if 11 - 11: i1I * I11iiIi11i1I % ooOOO + I1I
 for oOo00O in i11i1Iii1I1 :
  if ( i11i1Iii1I1 [ oOo00O ] < 0 ) :
   return IIiiii1IiIiII ( )
   if 59 - 59: Iii1i . OOooooOo00 - i1I
 return i11i1Iii1I1
 if 13 - 13: oOO
def IIii ( path ) :
 if os . path . exists ( path ) :
  if ".png" in path . lower ( ) [ - 4 : ] :
   try :
    return cairo . ImageSurface . create_from_png ( path )
    if 48 - 48: iI1iII1I1I1i / oOo0O00 % OOooooOo00
   except ( CairoError , IOError , MemoryError ) :
    ooO0Oo0o00 ( "Could not open file '%s'" % path )
  else :
   ooO0Oo0o00 ( "Invalid image format for file '%s'" % path )
   ooO0Oo0o00 ( "Only file format PNG is valid" )
 else :
  ooO0Oo0o00 ( "Could not open file '%s': file not found" % path )
  if 84 - 84: oOO . Oo + ooOOO / Oo . oOO
 return None
 if 20 - 20: OOooooOo00 + i1iiIII111 / I1I
def Ooo0OO ( color_dict , context , width , height ) :
 if 6 - 6: i1iiIII111
 I1I1 = color_dict [ "red" ] / 255
 oo0 = color_dict [ "green" ] / 255
 i11iIii = color_dict [ "blue" ] / 255
 if 40 - 40: IiIIii11Ii . i1 / Oo
 context . save ( )
 context . set_source_rgba ( I1I1 , oo0 , i11iIii , 1.0 )
 context . rectangle ( 0 , 0 , width , height )
 context . fill ( )
 context . restore ( )
 if 46 - 46: OOooooOo00 - OooOoo * I1Ii1I1 / Ooo0Ooo / Iii1i
def I11iIi1i ( image , image_pattern , width , height ) :
 if 49 - 49: IIiIIiIi11I1
 iIIiii1iI = image . get_width ( ) / width
 OOO = image . get_height ( ) / height
 if 83 - 83: oOO - Iii1i + ooOOO . i1I / ooOOO
 if iIIiii1iI < OOO :
  OOO = iIIiii1iI
  iII1II11iI1 = 0
  I1 = ( image . get_height ( ) - height * OOO ) / 2.0
 else :
  iIIiii1iI = OOO
  iII1II11iI1 = ( image . get_width ( ) - width * iIIiii1iI ) / 2.0
  I1 = 0
  if 56 - 56: I11iiIi11i1I
  if 69 - 69: I1I * Ooo0Ooo + i1iiIII111 . i1iiIII111 % Oo * oOo0O00
 OO0O0oo = cairo . Matrix ( xx = iIIiii1iI , yy = OOO , x0 = iII1II11iI1 , y0 = I1 )
 image_pattern . set_matrix ( OO0O0oo )
 if 54 - 54: I1Ii1I1 - i1I % ooo000 + Iii1i % oOo0O00 + I1I
def OOO0o0O0o ( image_surface , context , monitor ) :
 I111Iii1Ii = cairo . Context ( image_surface )
 if 26 - 26: Ii . i1
 I111Iii1Ii . set_source_surface ( image_surface )
 if 61 - 61: iI1iII1I1I1i . i1I - ooo000 / ooo000 - i1
 iIi , I1iiI1111II = monitor . width_in_pixels , monitor . height_in_pixels
 if 79 - 79: Ooo0Ooo % iI1iII1I1I1i % IIiIIiIi11I1 / ooOOO - ooOOO / I11iiIi11i1I
 context . save ( )
 if 63 - 63: ooOOO / i1i1i1111I - oOo0O00 * ooOOO / i1iiIII111 + oOO
 if 11 - 11: i1 / ooo000
 iII = I111Iii1Ii . get_source ( )
 I11iIi1i ( image_surface , iII , iIi , I1iiI1111II )
 context . set_source ( iII )
 if 43 - 43: Ooo0Ooo - I1I . ooo000 - Iii1i % i1I
 if 49 - 49: IiIIii11Ii . ooo000 + oOO - oOO
 context . rectangle ( 0 , 0 , iIi , I1iiI1111II )
 context . fill ( )
 if 78 - 78: i1 - ooOOO
 context . restore ( )
 if 56 - 56: ooo000 . ooo000 + I1Ii1I1 * iI1iII1I1I1i
def i111ii1I ( surface ) :
 try :
  return bytearray ( surface . get_data ( ) )
  if 18 - 18: Ii / ooo000 + I1I + iI1iII1I1I1i
 except NotImplementedError :
  pass
  if 42 - 42: ooOOO - ooOOO - i1i1i1111I
  if 61 - 61: oOO
 try :
  if 7 - 7: i1i1i1111I / Ii * Iii1i
  import gi
  if not hasattr ( gi , 'require_version' ) :
   raise ImportError
  gi . require_version ( "Gdk" , "3.0" )
  gi . require_foreign ( 'cairo' )
  from gi . repository import Gdk
  if not hasattr ( Gdk , 'SELECTION_PRIMARY' ) :
   raise ImportError
   if 32 - 32: OOooooOo00 . OooOoo
 except ( ImportError , ValueError ) as ii1i11i1 :
  i1I1 ( "Could not load PyGObject: %s" % ii1i11i1 )
  sys . exit ( 1 )
  if 31 - 31: Oo - i1I
 IIIi1111iiIi1 = surface . get_width ( )
 I1II1ii111i = surface . get_height ( )
 I1i1iI1I1Ii1 = Gdk . pixbuf_get_from_surface ( surface , 0 , 0 , IIIi1111iiIi1 , I1II1ii111i )
 if 83 - 83: Ooo0Ooo . Oo - Ooo0Ooo
 if 47 - 47: OooOoo - I1Ii1I1 - I11iiIi11i1I * ooOOO * oOO % IIiIIiIi11I1
 O0OOooOOoO000 = I1i1iI1I1Ii1 . add_alpha ( False , 0 , 0 , 0 )
 OO = O0OOooOOoO000 . get_pixels ( )
 if 42 - 42: I1I - IiIIii11Ii
 if 34 - 34: OOooooOo00 + ooOOO * oOO
 return ii1 ( OO )
 if 53 - 53: i1 % IIiIIiIi11I1 * IIiIIiIi11I1 * iI1iII1I1I1i
def ii1 ( bgra_pixels ) :
 iiI1iI = list ( bgra_pixels )
 O0OO00OO0O = bytearray ( b'' )
 for Ooo0oO in range ( 0 , len ( iiI1iI ) , 4 ) :
  O0OO00OO0O . append ( iiI1iI [ Ooo0oO + 2 ] )
  O0OO00OO0O . append ( iiI1iI [ Ooo0oO + 1 ] )
  O0OO00OO0O . append ( iiI1iI [ Ooo0oO ] )
  O0OO00OO0O . append ( iiI1iI [ Ooo0oO + 3 ] )
  if 16 - 16: I1Ii1I1 % I1I / IIiIIiIi11I1 * i1I + OOooooOo00 % oOo0O00
 return O0OO00OO0O
 if 13 - 13: i1 + IiIIii11Ii
def I1Ii ( surface , pixmap , monitor ) :
 oOoo0OOOOOoo = i111ii1I ( surface )
 if 33 - 33: i1i1i1111I . IIiIIiIi11I1 - i1I . Ii
 if 20 - 20: oOo0O00 % i1i1i1111I
 if 32 - 32: oOO
 oOOOO0OO00 = monitor . width_in_pixels
 i1iI1 = monitor . height_in_pixels
 if 11 - 11: I1Ii1I1 / oOO
 iI = oOOOO0OO00 * i1iI1
 assert len ( oOoo0OOOOOoo ) == iI * 4 , "Invalid pixel data, expected %d (%dx%d * 4) bytes, got %d" % ( iI * 4 , oOOOO0OO00 , i1iI1 , len ( oOoo0OOOOOoo ) )
 if 58 - 58: IIiIIiIi11I1 % Ii + oOo0O00 / oOo0O00 * iI1iII1I1I1i * i1i1i1111I
 if 88 - 88: i1I + I1I
 if 55 - 55: oOO
 iiiiiI = pixmap . create_gc ( )
 if 77 - 77: oOo0O00 % Oo - oOo0O00 - ooo000 * I11iiIi11i1I + oOO
 if 64 - 64: OOooooOo00 . Ooo0Ooo . i1iiIII111 * OOooooOo00
 if 33 - 33: i1i1i1111I
 if 30 - 30: i1I % ooOOO . Ii % IIiIIiIi11I1 / iI1iII1I1I1i % ooOOO
 if 24 - 24: IIiIIiIi11I1 - IIiIIiIi11I1 . Ooo0Ooo + i1iiIII111 + Oo
 if 21 - 21: IIiIIiIi11I1 - ooo000 + oOO
 if 5 - 5: i1iiIII111 . i1iiIII111 + ooo000 . I11iiIi11i1I
 Iii1I1I1 = 16384
 oO0oO = ( Iii1I1I1 << 2 ) - request . PutImage . _request . static_size
 Oo0 = oO0oO / surface . get_stride ( )
 if 78 - 78: I1Ii1I1 * oOo0O00
 Iii = int ( Oo0 * oOOOO0OO00 )
 if 60 - 60: OooOoo
 Ooo0oO = 0
 O0OOOOoO0o = 0
 o00ooOOO0Oo = 0
 O00OoO0OOO0 = monitor . x
 Oo0o0Oo = monitor . y
 if Iii > oOOOO0OO00 :
  if 100 - 100: i1iiIII111 . IIiIIiIi11I1 * ooo000 * ooo000
  Iioo0Oo0oO0 = Iii // oOOOO0OO00
  while Ooo0oO < len ( oOoo0OOOOOoo ) :
   I1iiI1111II = max ( min ( Iioo0Oo0oO0 , i1iI1 - o00ooOOO0Oo ) , 1 )
   iII11I1iI = oOOOO0OO00 * I1iiI1111II * 4
   O0O0o0oo00Oo = oOoo0OOOOOoo [ Ooo0oO : Ooo0oO + iII11I1iI ]
   pixmap . put_image ( iiiiiI , O00OoO0OOO0 , Oo0o0Oo , oOOOO0OO00 , I1iiI1111II , X . ZPixmap , 24 , 0 , O0O0o0oo00Oo )
   o00ooOOO0Oo += Iioo0Oo0oO0
   Oo0o0Oo += Iioo0Oo0oO0
   Ooo0oO += iII11I1iI
 else :
  if 96 - 96: Ooo0Ooo
  if 13 - 13: Oo * I1Ii1I1 - oOo0O00 * Ii . Ii + oOo0O00
  Iioo0Oo0oO0 = 1
  while Ooo0oO < len ( oOoo0OOOOOoo ) :
   iIi = max ( min ( Iii , oOOOO0OO00 - O0OOOOoO0o ) , 1 )
   iII11I1iI = iIi * 4
   O0O0o0oo00Oo = oOoo0OOOOOoo [ Ooo0oO : Ooo0oO + iII11I1iI ]
   pixmap . put_image ( iiiiiI , O00OoO0OOO0 , Oo0o0Oo , iIi , Iioo0Oo0oO0 , X . ZPixmap , 24 , 0 , O0O0o0oo00Oo )
   O0OOOOoO0o += iIi
   O00OoO0OOO0 += iIi
   Ooo0oO += iIi * 4
   if 46 - 46: OooOoo - I11iiIi11i1I / Ooo0Ooo
   if O0OOOOoO0o >= oOOOO0OO00 :
    if 73 - 73: I1Ii1I1 / i1i1i1111I / ooo000 % i1 % i1I - OooOoo
    o00ooOOO0Oo += 1
    Oo0o0Oo += 1
    O0OOOOoO0o = 0
    O00OoO0OOO0 = monitor . x
    if 30 - 30: ooOOO * ooOOO - Iii1i * iI1iII1I1I1i
def oOOOOOOoOOooO0O0 ( monitors ) :
 O0 = 0
 O0Ii1Ii1 = 0
 if 25 - 25: OooOoo + Oo * Ii * iI1iII1I1I1i + Ii
 if 75 - 75: OooOoo * oOo0O00 . i1iiIII111
 for oo0O0 in monitors :
  if oo0O0 . width_in_pixels + oo0O0 . x > O0 :
   O0 = oo0O0 . width_in_pixels + oo0O0 . x
  if oo0O0 . height_in_pixels + oo0O0 . y > O0Ii1Ii1 :
   O0Ii1Ii1 = oo0O0 . height_in_pixels + oo0O0 . y
   if 65 - 65: ooOOO / oOo0O00 - i1iiIII111
 return O0 , O0Ii1Ii1
 if 15 - 15: OooOoo . ooo000 / IiIIii11Ii % i1i1i1111I
class o0oOO0 ( ) :
 if 96 - 96: i1I + IiIIii11Ii - i1 . Iii1i - oOO % i1iiIII111
 def __init__ ( self , color , image_surface ) :
  self . color = color
  self . input_surface = image_surface
  if 79 - 79: i1i1i1111I * iI1iII1I1I1i
  try :
   self . display = display . Display ( )
  except DisplayConnectionError as ii1i11i1 :
   i1I1 ( "Failed to open display: %s" % ii1i11i1 )
   sys . exit ( 1 )
   if 90 - 90: Ooo0Ooo * OooOoo . Ii
  self . screen = self . display . screen ( )
  self . root = self . screen . root
  if 5 - 5: Oo - i1 . oOO
  self . depth = self . screen . root_depth
  assert self . depth == 24 or self . depth == 32 , "Depth of screen is %d, must be 24 or 32" % self . depth
  if 18 - 18: IiIIii11Ii - oOO * i1I - OooOoo
  if 54 - 54: IIiIIiIi11I1 . Ooo0Ooo % Ii + IiIIii11Ii * iI1iII1I1I1i / iI1iII1I1I1i
  self . last_resize = 0
  self . resize_wait = 0.1
  if 31 - 31: IiIIii11Ii . IiIIii11Ii % Ii
  if 51 - 51: Oo / i1i1i1111I - I1I
  signal . signal ( signal . SIGTERM , self . exit )
  if 83 - 83: Iii1i % i1iiIII111 . OooOoo / I1I % oOO . I1I
  if 76 - 76: i1iiIII111 / OooOoo
  self . set_root_background ( )
  if 77 - 77: ooOOO
 def exit ( self , * args ) :
  try :
   self . display . close ( )
  finally :
   sys . exit ( os . EX_OK )
   if 19 - 19: ooOOO % I1Ii1I1
 def set_root_background ( self ) :
  if 15 - 15: OooOoo . IiIIii11Ii . i1I / Iii1i + ooOOO / Ii
  Ii1iIII11i = randr . get_monitors ( self . root , is_active = True ) . monitors
  O0 , O0Ii1Ii1 = oOOOOOOoOOooO0O0 ( Ii1iIII11i )
  if 58 - 58: OOooooOo00 / I11iiIi11i1I . iI1iII1I1I1i + Iii1i * Ii
  if 62 - 62: Oo - iI1iII1I1I1i - i1i1i1111I . i1iiIII111
  iI11 = self . root . create_pixmap ( O0 , O0Ii1Ii1 , self . depth )
  if 75 - 75: i1iiIII111 * OOooooOo00 - oOo0O00 % I11iiIi11i1I - OOooooOo00
  if 56 - 56: Oo
  if 84 - 84: I1I % iI1iII1I1I1i - Ooo0Ooo / iI1iII1I1I1i + Ooo0Ooo - Oo
  for oo0O0 in Ii1iIII11i :
   oOOOO0OO00 = oo0O0 . width_in_pixels
   i1iI1 = oo0O0 . height_in_pixels
   if 41 - 41: ooOOO + OooOoo + IIiIIiIi11I1 * i1i1i1111I
   if oOOOO0OO00 == 0 or i1iI1 == 0 :
    continue
    if 12 - 12: i1i1i1111I
    if 56 - 56: IiIIii11Ii
   i11I1iII1I1 = cairo . ImageSurface ( cairo . FORMAT_ARGB32 ,
 oOOOO0OO00 , i1iI1 )
   IIIi11ii1Ii = cairo . Context ( i11I1iII1I1 )
   if 14 - 14: IiIIii11Ii % ooOOO . i1I
   if 29 - 29: OOooooOo00 % oOO % OOooooOo00 . ooOOO
   Ooo0OO ( self . color , IIIi11ii1Ii , oOOOO0OO00 , i1iI1 )
   if 4 - 4: oOo0O00 + i1iiIII111
   if 45 - 45: I1Ii1I1
   if self . input_surface :
    OOO0o0O0o ( self . input_surface , IIIi11ii1Ii , oo0O0 )
    if 19 - 19: ooo000 * OooOoo . Iii1i * I11iiIi11i1I . I1I
   I1Ii ( i11I1iII1I1 , iI11 , oo0O0 )
   if 49 - 49: i1iiIII111 - IiIIii11Ii / i1iiIII111 + i1I
   if 77 - 77: Ii
  self . root . change_attributes ( background_pixmap = iI11 )
  self . root . clear_area ( )
  if 20 - 20: Ii % i1i1i1111I
 def loop ( self ) :
  if 35 - 35: Ooo0Ooo * OOooooOo00 - Ooo0Ooo - ooOOO
  if 28 - 28: IiIIii11Ii . Oo - i1I + I11iiIi11i1I - oOo0O00
  self . root . xrandr_select_input ( randr . RRCrtcChangeNotifyMask )
  if 6 - 6: OOooooOo00 - Ii
  try :
   while True :
    if 1 - 1: I1I + OooOoo
    OooO0Oo = self . display . next_event ( )
    self . handle_event ( OooO0Oo )
    if 17 - 17: i1 % oOO % IiIIii11Ii * i1i1i1111I
  except ( KeyboardInterrupt , SystemExit ) as ii1i11i1 :
   pass
  except Exception as ii1i11i1 :
   i1I1 ( "Caught exception (%s)" % ii1i11i1 )
  finally :
   self . exit ( )
   if 51 - 51: Ooo0Ooo . iI1iII1I1I1i . i1iiIII111 . Ooo0Ooo % ooo000 % Ooo0Ooo
 def handle_event ( self , event ) :
  ooOo0O0O = self . display . extension_event
  if 12 - 12: i1 . i1I - I11iiIi11i1I - i1i1i1111I
  if 51 - 51: i1iiIII111 * i1iiIII111 / I1Ii1I1
  if ( event . type == ooOo0O0O . CrtcChangeNotify [ 0 ] and
 event . sub_code == ooOo0O0O . CrtcChangeNotify [ 1 ] ) :
   if 10 - 10: Oo * I11iiIi11i1I % IiIIii11Ii / OooOoo + i1
   if 14 - 14: I1I + I1Ii1I1
   i1II = time . time ( ) < self . last_resize + self . resize_wait
   if i1II :
    return
    if 97 - 97: iI1iII1I1I1i % i1I * OOooooOo00 * i1iiIII111 + OooOoo
    if 57 - 57: IIiIIiIi11I1
   self . set_root_background ( )
   self . last_resize = time . time ( )
   if 57 - 57: ooOOO + Ii % I11iiIi11i1I + oOo0O00 . iI1iII1I1I1i - Ii
def Ii1i11 ( ) :
 O00oO00oO0O = OptionParser ( version = "1.0" ,
 usage = "%prog [--color=<hex color>] [--image=<path>]" ,
 description = "Set root background color and/or background image" )
 if 65 - 65: iI1iII1I1I1i . Oo
 O00oO00oO0O . add_option ( "--color" , help = "Set color based on the input hex string" ,
 dest = "color" , metavar = "COLOR" )
 if 44 - 44: I11iiIi11i1I . I1Ii1I1 * i1 . iI1iII1I1I1i * I11iiIi11i1I - I11iiIi11i1I
 O00oO00oO0O . add_option ( "--image" , help = "Set background image to specified png file" ,
 dest = "image" , metavar = "PATH" )
 if 79 - 79: IiIIii11Ii + oOo0O00
 ( O00o00O , I11 ) = O00oO00oO0O . parse_args ( )
 if 50 - 50: OOooooOo00 + i1iiIII111 / i1i1i1111I
 if not O00o00O . color and not O00o00O . image :
  i1I1 ( "You have to provide a color or an image path" )
  sys . exit ( 1 )
  if 75 - 75: IiIIii11Ii / ooo000 + OOooooOo00 / i1i1i1111I * oOO + ooo000
 if cairo is None :
  i1I1 ( "Could not load Pycairo" )
  sys . exit ( 1 )
  if 83 - 83: I11iiIi11i1I / Ooo0Ooo . I11iiIi11i1I
 oOooOOo = "#000000"
 if O00o00O . color :
  oOo00O = OO0o000o ( O00o00O . color , oOooOOo )
 else :
  oOo00O = OO0o000o ( oOooOOo )
  if 29 - 29: i1i1i1111I / oOo0O00
 if O00o00O . image :
  iI1i1Iiii11i = IIii ( O00o00O . image )
 else :
  iI1i1Iiii11i = None
  if 93 - 93: Ooo0Ooo . i1 + OOooooOo00 - oOo0O00
 ooOOoO00OO = o0oOO0 ( oOo00O , iI1i1Iiii11i )
 ooOOoO00OO . loop ( )
 if 99 - 99: I11iiIi11i1I - Ooo0Ooo % I1Ii1I1
if __name__ == '__main__' :
 Ii1i11 ( )
# dd678faae9ac167bc83abf78e5cb2f3f0688d3a3
