]> code.delx.au - offlineimap/blobdiff - offlineimap/head/offlineimap/ui/Curses.py
/offlineimap/head: changeset 367
[offlineimap] / offlineimap / head / offlineimap / ui / Curses.py
index f005792eb060e5c5551d94384cc463e327a4e48d..52f8f11e477ee4d3952991fc27d05fca84cb2b09 100644 (file)
 from Blinkenlights import BlinkenBase
 from UIBase import UIBase
 from threading import *
-import thread, time
+import thread, time, sys, os, signal, time
 from offlineimap import version, threadutil
 from offlineimap.threadutil import MultiLock
 
 import curses, curses.panel, curses.textpad, curses.wrapper
-from debuglock import DebuggingLock
 
 acctkeys = '1234567890abcdefghijklmnoprstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-=;/.,'
 
 class CursesUtil:
     def __init__(self):
-        self.pairs = {self._getpairindex(curses.COLOR_WHITE,
-                                         curses.COLOR_BLACK): 0}
-        self.start()
-        self.nextpair = 1
         self.pairlock = Lock()
         self.iolock = MultiLock()
+        self.start()
+
+    def initpairs(self):
+        self.pairlock.acquire()
+        try:
+            self.pairs = {self._getpairindex(curses.COLOR_WHITE,
+                                             curses.COLOR_BLACK): 0}
+            self.nextpair = 1
+        finally:
+            self.pairlock.release()
 
     def lock(self):
         self.iolock.acquire()
@@ -64,6 +69,8 @@ class CursesUtil:
         return '%d/%d' % (fg,bg)
 
     def getpair(self, fg, bg):
+        if not self.has_color:
+            return 0
         pindex = self._getpairindex(fg, bg)
         self.pairlock.acquire()
         try:
@@ -97,6 +104,7 @@ class CursesUtil:
         self.stdscr.clear()
         self.stdscr.refresh()
         (self.height, self.width) = self.stdscr.getmaxyx()
+        self.initpairs()
 
     def stop(self):
         if not hasattr(self, 'stdscr'):
@@ -201,7 +209,10 @@ class CursesThreadFrame:
 
     def display(self):
         def lockedstuff():
-            self.window.addstr(self.y, self.x, '.', self.color)
+            if self.getcolor() == 'black':
+                self.window.addstr(self.y, self.x, ' ', self.color)
+            else:
+                self.window.addstr(self.y, self.x, '.', self.color)
             self.c.stdscr.move(self.c.height - 1, self.c.width - 1)
             self.window.refresh()
         self.c.locked(lockedstuff)
@@ -229,9 +240,9 @@ class InputHandler:
     def __init__(s, util):
         s.c = util
         s.bgchar = None
-        s.inputlock = DebuggingLock('inputlock')
+        s.inputlock = Lock()
         s.lockheld = 0
-        s.statuslock = DebuggingLock('statuslock')
+        s.statuslock = Lock()
         s.startup = Event()
         s.startthread()
 
@@ -299,7 +310,7 @@ class InputHandler:
 class Blinkenlights(BlinkenBase, UIBase):
     def init_banner(s):
         s.af = {}
-        s.aflock = DebuggingLock('aflock')
+        s.aflock = Lock()
         s.c = CursesUtil()
         s.text = []
         BlinkenBase.init_banner(s)
@@ -308,6 +319,58 @@ class Blinkenlights(BlinkenBase, UIBase):
         s.gettf().setcolor('red')
         s._msg(version.banner)
         s.inputhandler.set_bgchar(s.keypress)
+        signal.signal(signal.SIGWINCH, s.resizehandler)
+        s.resizelock = Lock()
+        s.resizecount = 0
+
+    def resizehandler(s, signum, frame):
+        s.resizeterm()
+
+    def resizeterm(s, dosleep = 1):
+        if not s.resizelock.acquire(0):
+            s.resizecount += 1
+            return
+        signal.signal(signal.SIGWINCH, signal.SIG_IGN)
+        s.aflock.acquire()
+        s.c.lock()
+        s.resizecount += 1
+        while s.resizecount:
+            s.c.reset()
+            s.setupwindows()
+            s.resizecount -= 1
+        s.c.unlock()
+        s.aflock.release()
+        s.resizelock.release()
+        signal.signal(signal.SIGWINCH, s.resizehandler)
+        if dosleep:
+            time.sleep(1)
+            s.resizeterm(0)
+
+    def isusable(s):
+        # Not a terminal?  Can't use curses.
+        if not sys.stdout.isatty() and sys.stdin.isatty():
+            return 0
+
+        # No TERM specified?  Can't use curses.
+        try:
+            if not len(os.environ['TERM']):
+                return 0
+        except: return 0
+
+        # ncurses doesn't want to start?  Can't use curses.
+        # This test is nasty because initscr() actually EXITS on error.
+        # grr.
+
+        pid = os.fork()
+        if pid:
+            # parent
+            return not os.WEXITSTATUS(os.waitpid(pid, 0)[1])
+        else:
+            # child
+            curses.initscr()
+            curses.endwin()
+            # If we didn't die by here, indicate success.
+            sys.exit(0)
 
     def keypress(s, key):
         if key > 255:
@@ -381,9 +444,12 @@ class Blinkenlights(BlinkenBase, UIBase):
             s.c.unlock()
 
     def setupwindow_drawbanner(s):
-        s.bannerwindow.bkgd(' ', curses.A_BOLD | \
-                            s.c.getpair(curses.COLOR_WHITE,
-                                        curses.COLOR_BLUE))
+        if s.c.has_color:
+            color = s.c.getpair(curses.COLOR_WHITE, curses.COLOR_BLUE) | \
+                    curses.A_BOLD
+        else:
+            color = curses.A_REVERSE
+        s.bannerwindow.bkgd(' ', color) # Fill background with that color
         s.bannerwindow.addstr("%s %s" % (version.productname,
                                          version.versionstr))
         s.bannerwindow.addstr(0, s.bannerwindow.getmaxyx()[1] - len(version.copyright) - 1,
@@ -392,7 +458,11 @@ class Blinkenlights(BlinkenBase, UIBase):
         s.bannerwindow.noutrefresh()
 
     def setupwindow_drawlog(s):
-        s.logwindow.bkgd(' ', s.c.getpair(curses.COLOR_WHITE, curses.COLOR_BLACK))
+        if s.c.has_color:
+            color = s.c.getpair(curses.COLOR_WHITE, curses.COLOR_BLACK)
+        else:
+            color = curses.A_NORMAL
+        s.logwindow.bkgd(' ', color)
         for line, color in s.text:
             s.logwindow.addstr("\n" + line, color)
         s.logwindow.noutrefresh()
@@ -476,7 +546,7 @@ if __name__ == '__main__':
     x = Blinkenlights(None)
     x.init_banner()
     import time
-    time.sleep(10)
+    time.sleep(5)
     x.c.stop()
     fgs = {'black': curses.COLOR_BLACK, 'red': curses.COLOR_RED,
            'green': curses.COLOR_GREEN, 'yellow': curses.COLOR_YELLOW,
@@ -511,7 +581,7 @@ if __name__ == '__main__':
     win4.refresh()
     x.stdscr.refresh()
     import time
-    time.sleep(40)
+    time.sleep(5)
     x.stop()
     print x.has_color
     print x.height