📄 mclock.py
字号:
#! /usr/bin/env python# "M Clock"## An implementation in software of an original design by Rob Juda.# Clock implementation: Guido van Rossum.# Alarm and Gong features: Sape Mullender.## XXX TO DO:# add arguments to specify initial window position and size# find out local time zone difference automatically# add a date indicator# allow multiple alarms# allow the menu to change more parametersimport sysfrom gl import *from GL import *from DEVICE import *import timeimport getoptimport stringimport osfrom math import piimport mathFULLC = 3600 # Full circle in 1/10-ths of a degreeMIDN = 900 # Angle of the 12 o'clock positionR, G, B = 0, 1, 2 # Indices of colors in RGB listHOUR = 3600 # Number of seconds per hourMINUTE = 60 # Number of seconds per minuteclass struct: pass # Class to define featureless structuresGl = struct() # Object to hold writable global variables# Default constants (used in multiple places)SCREENBG = 127, 156, 191NPARTS = 9TITLE = 'M Clock'# Set timezone, check for daylight saving timeTZDIFF = time.timezoneif time.localtime(time.time())[-1]: TZDIFF = time.altzone# Default parametersGl.foreground = 0 # If set, run in the foregroundGl.fullscreen = 0 # If set, run on full screenGl.tzdiff = TZDIFF # Seconds west of Greenwich (winter time)Gl.nparts = NPARTS # Number of parts each circle is divided in (>= 2)Gl.debug = 0 # If set, print debug outputGl.doublebuffer = 1 # If set, use double bufferingGl.update = 0 # Update interval; seconds hand is suppressed if > 1Gl.colorsubset = 0 # If set, display only a subset of the colorsGl.cyan = 0 # If set, display cyan overlay (big hand)Gl.magenta = 0 # If set, display magenta overlay (little hand)Gl.yellow = 0 # If set, display yellow overlay (fixed background)Gl.black = 0 # If set, display black overlay (hands)Gl.colormap = 0 # If set, use colormap mode instead of RGB modeGl.warnings = 0 # If set, print warningsGl.title = '' # Window title (default set later)Gl.name = 'mclock' # Window title for resourcesGl.border = 1 # If set, use a window border (and title)Gl.bg = 0, 0, 0 # Background color R, G, B valueGl.iconic = 0 # Set in iconic stateGl.fg = 255, 0, 0 # Alarm background RGB (either normal or alarm)Gl.ox,Gl.oy = 0,0 # Window originGl.cx,Gl.cy = 0,0 # Window sizeGl.alarm_set = 0 # Alarm on or offGl.alarm_on = 0 # Alarm is ringingGl.alarm_time = 0 # Alarm time in seconds after midnightGl.alarm_hours = 0 # Alarm hour setting, 24 hour clockGl.alarm_minutes = 0 # Alarm minutes settingGl.alarm_rgb = 0,0,0 # Alarm display RGB colorsGl.alarm_cmd = '' # Command to execute when alarm goes offGl.mouse2down = 0 # Mouse button stateGl.mouse3down = 0 # Mouse button stateGl.gong_cmd = '' # Command to execute when chimes go offGl.gong_int = 3600 # Gong intervalGl.indices = R, G, B # Colors (permuted when alarm is on)def main(): # sys.stdout = sys.stderr # All output is errors/warnings etc. # try: args = getoptions() except string.atoi_error, value: usage(string.atoi_error, value) except getopt.error, msg: usage(getopt.error, msg) # if args: realtime = 0 hours = string.atoi(args[0]) minutes = seconds = 0 if args[1:]: minutes = string.atoi(args[1]) if args[2:]: seconds = string.atoi(args[2]) localtime = ((hours*60)+minutes)*60+seconds else: realtime = 1 # if Gl.title == '': if realtime: Gl.title = TITLE else: title = '' for arg in args: title = title + ' ' + arg Gl.title = title[1:] del title # wid = makewindow() Gl.ox,Gl.oy = getorigin() Gl.cx,Gl.cy = getsize() initmenu() clearall() # if not Gl.update: Gl.update = 60 # if Gl.update <= 1: Gl.timernoise = 6 else: Gl.timernoise = 60 noise(TIMER0, Gl.timernoise) # qdevice(WINSHUT) qdevice(WINQUIT) qdevice(ESCKEY) if realtime: qdevice(TIMER0) qdevice(REDRAW) qdevice(WINFREEZE) qdevice(WINTHAW) qdevice(MENUBUTTON) # MOUSE1 qdevice(MOUSE3) # Left button qdevice(MOUSE2) # Middle button unqdevice(INPUTCHANGE) # lasttime = 0 Gl.change = 1 while 1: if realtime: localtime = int(time.time() - Gl.tzdiff) if Gl.alarm_set: if localtime%(24*HOUR) == Gl.alarm_time: # Ring the alarm! if Gl.debug: print 'Rrrringg!' Gl.alarm_on = 1 if Gl.alarm_cmd <> '': d = os.system(Gl.alarm_cmd+' '+`Gl.alarm_time/3600`+' '+`(Gl.alarm_time/60)%60` + ' &') Gl.change = 1 clearall() if Gl.alarm_on: if (localtime - Gl.alarm_time) % (24*HOUR) > 300: # More than 5 minutes away from alarm Gl.alarm_on = 0 if Gl.debug: print 'Alarm turned off' Gl.change = 1 clearall() Gl.indices = R, G, B else: if localtime % 2 == 0: # Permute color indices Gl.indices = Gl.indices[2:] + Gl.indices[:2] Gl.change = 1 if Gl.gong_cmd <> '' and localtime%Gl.gong_int == 0: d = os.system(Gl.gong_cmd+' '+`(localtime/3600)%24`+' '+`(localtime/60)%60` + ' &') if localtime/Gl.update <> lasttime/Gl.update: if Gl.debug: print 'new time' Gl.change = 1 if Gl.change: if Gl.debug: print 'drawing' doit(localtime) lasttime = localtime Gl.change = 0 dev, data = qread() if Gl.debug and dev <> TIMER0: print dev, data if dev == TIMER0: if Gl.debug > 1: print dev, data elif dev == MOUSE3: mousex = getvaluator(MOUSEX) mousey = getvaluator(MOUSEY) if mouseclick(3, data, mousex, mousey): Gl.change = 1 elif dev == MOUSE2: mousex = getvaluator(MOUSEX) mousey = getvaluator(MOUSEY) if mouseclick(2, data, mousex, mousey): Gl.change = 1 elif dev == MOUSEX: mousex = data if Gl.mouse2down: mouse2track(mousex, mousey) if Gl.mouse3down: mouse3track(mousex, mousey) elif dev == MOUSEY: mousey = data if Gl.mouse2down: mouse2track(mousex, mousey) if Gl.mouse3down: mouse3track(mousex, mousey) elif dev == REDRAW or dev == REDRAWICONIC: if Gl.debug: if dev == REDRAW: print 'REDRAW' else: print 'REDRAWICONIC' reshapeviewport() Gl.ox,Gl.oy = getorigin() Gl.cx,Gl.cy = getsize() Gl.change = 1 clearall() elif dev == MENUBUTTON: if Gl.debug: print 'MENUBUTTON' handlemenu() elif dev == WINFREEZE: if Gl.debug: print 'WINFREEZE' Gl.iconic = 1 noise(TIMER0, 60*60) # Redraw every 60 seconds only elif dev == WINTHAW: if Gl.debug: print 'WINTHAW' Gl.iconic = 0 noise(TIMER0, Gl.timernoise) Gl.change = 1 elif dev == ESCKEY or dev == WINSHUT or dev == WINQUIT: if Gl.debug: print 'Exit' sys.exit(0)def getoptions(): optlist, args = getopt.getopt(sys.argv[1:], 'A:a:B:bc:dFfG:g:n:sT:t:u:wCMYK') for optname, optarg in optlist: if optname == '-A': Gl.fg = eval(optarg) # Should be (r,g,b) elif optname == '-a': Gl.alarm_cmd = optarg elif optname == '-B': Gl.bg = eval(optarg) # Should be (r,g,b) elif optname == '-b': Gl.border = 0 elif optname == '-c': Gl.colormap = string.atoi(optarg) elif optname == '-d': Gl.debug = Gl.debug + 1 Gl.warnings = 1 elif optname == '-F': Gl.foreground = 1 elif optname == '-f': Gl.fullscreen = 1 elif optname == '-G': Gl.gong_int = 60*string.atoi(optarg) elif optname == '-g': Gl.gong_cmd = optarg elif optname == '-n': Gl.nparts = string.atoi(optarg) elif optname == '-s': Gl.doublebuffer = 0 elif optname == '-T': Gl.title = Gl.name = optarg elif optname == '-t': Gl.tzdiff = string.atoi(optarg) elif optname == '-u': Gl.update = string.atoi(optarg) elif optname == '-w': Gl.warnings = 1 elif optname == '-C': Gl.cyan = Gl.colorsubset = 1 elif optname == '-M': Gl.magenta = Gl.colorsubset = 1 elif optname == '-Y': Gl.yellow = Gl.colorsubset = 1 elif optname == '-K': Gl.black = Gl.colorsubset = 1 else: print 'Unsupported option', optname return argsdef usage(exc, msg): if sys.argv: progname = os.path.basename(sys.argv[0]) else: progname = 'mclock' # print progname + ':', if exc == string.atoi_error: print 'non-numeric argument:', print msg # print 'usage:', progname, '[options] [hh [mm [ss]]]' # print '-A r,g,b : alarm background red,green,blue [255,0,0]' print '-a cmd : shell command executed when alarm goes off' print '-B r,g,b : background red,green,blue [0,0,0]' print ' (-B SCREENBG uses the default screen background)' print '-b : suppress window border and title' print '-c cmapid : select explicit colormap' print '-d : more debug output (implies -F, -w)' print '-F : run in foreground' print '-f : use full screen' print '-G intrvl : interval between chimes in minutes [60]' print '-g cmd : shell command executed when chimes go off' print '-s : single buffer mode' print '-w : print various warnings' print '-n nparts : number of parts [' + `NPARTS` + ']' print '-T title : alternate window title [\'' + TITLE + '\']' print '-t tzdiff : time zone difference [' + `TZDIFF` + ']' print '-u update : update interval [60]' print '-CMYK : Cyan, Magenta, Yellow or blacK overlay only' print 'if hh [mm [ss]] is specified, display that time statically' print 'on machines with < 12 bitplanes, -s is forced on' # sys.exit(2)def doit(localtime): hands = makehands(localtime) list = makelist(hands) render(list, hands)def makehands(localtime): localtime = localtime % (12*HOUR) seconds_hand = MIDN + FULLC - (localtime*60) % FULLC big_hand = (MIDN + FULLC - (localtime%HOUR)) % FULLC little_hand = (MIDN + FULLC - ((localtime/12) % HOUR)) % FULLC return little_hand, big_hand, seconds_handdef makelist(hands): little_hand, big_hand, seconds_hand = hands total = [] if Gl.cyan or not Gl.colorsubset: total = total + makesublist(big_hand, Gl.indices[0]) if Gl.magenta or not Gl.colorsubset: total = total + makesublist(little_hand, Gl.indices[1]) if Gl.yellow or not Gl.colorsubset: total = total + makesublist(MIDN, Gl.indices[2]) total.sort() return totaldef makesublist(first, icolor): list = [] alpha = FULLC/Gl.nparts a = first - alpha/2 for i in range(Gl.nparts): angle = (a + i*alpha + FULLC) % FULLC value = 255*(Gl.nparts-1-i)/(Gl.nparts-1) list.append((angle, icolor, value)) list.sort() a, icolor, value = list[0] if a <> 0: a, icolor, value = list[len(list)-1] t = 0, icolor, value list.insert(0, t) return listdef rgb_fg(): return Gl.fg # Obsolete code: if Gl.alarm_on: return Gl.bg else: return Gl.fgdef rgb_bg(): return Gl.bg
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -