1 #ifndef __YXCONTEXT_H
2 #define __YXCONTEXT_H
3 
4 #ifndef NULLQUARK
5 #include <X11/Xresource.h>
6 #endif
7 
8 class YAnyContext {
9 protected:
10     typedef void* AnyPointer;
11 
12 private:
13     XContext unique;
14     const char* title;
15     const bool verbose;
16 
context()17     XContext context() {
18         if (unique == 0) {
19             unique = XUniqueContext();
20             if (verbose) {
21                 tlog("%s: created", title);
22             }
23         }
24         return unique;
25     }
26 
dpy()27     Display* dpy() const { return xapp->display(); }
28 
29 public:
30     YAnyContext(const char* title = nullptr, bool verbose = false) :
31         unique(0),
32         title(title),
33         verbose(verbose)
34     {
35     }
36 
~YAnyContext()37     ~YAnyContext() {
38         if (verbose) {
39             tlog("%s: destroyed", title);
40         }
41     }
42 
43     // store mapping of window to pointer
save(Window w,AnyPointer p)44     void save(Window w, AnyPointer p) {
45         const char* q = static_cast<const char *>(p);
46         XSaveContext(dpy(), w, context(), q);
47         if (verbose) {
48             tlog("%s: save 0x%lx to %p", title, w, p);
49         }
50     }
51 
52     // lookup pointer by window
find(Window w,AnyPointer * p)53     bool find(Window w, AnyPointer* p) {
54         char* q = nullptr;
55         int rc = XFindContext(dpy(), w, context(), &q);
56         if (verbose) {
57             if (rc == 0)
58                 tlog("%s: find 0x%lx found %p", title, w,
59                         reinterpret_cast<void *>(p));
60             else
61                 tlog("%s: find 0x%lx not found", title, w);
62         }
63         *p = q;
64         return rc == 0;
65     }
66 
67     // remove mapping of window to pointer
remove(Window w)68     bool remove(Window w) {
69         int rc = XDeleteContext(dpy(), w, context());
70         if (verbose) {
71             if (rc == 0)
72                 tlog("%s: remove for 0x%lx", title, w);
73             else
74                 tlog("%s: remove for 0x%lx failed", title, w);
75         }
76         return rc == 0;
77     }
78 };
79 
80 template <typename T>
81 class YContext : private YAnyContext {
82     typedef T* TPtr;
83 public:
84     YContext(const char* title = nullptr, bool verbose = false) :
YAnyContext(title,verbose)85         YAnyContext(title, verbose) { }
86 
87     // store mapping of window to pointer
save(Window w,TPtr p)88     void save(Window w, TPtr p) {
89         YAnyContext::save(w, AnyPointer(p));
90     }
91 
92     // lookup pointer by window
find(Window w,TPtr * ptr)93     bool find(Window w, TPtr* ptr) {
94         AnyPointer p = nullptr;
95         if (YAnyContext::find(w, &p)) {
96             *ptr = TPtr(p);
97             return true;
98         }
99         return false;
100     }
101 
102     // lookup pointer by window
find(Window w)103     TPtr find(Window w) {
104         AnyPointer p = nullptr;
105         YAnyContext::find(w, &p);
106         return TPtr(p);
107     }
108 
109     // remove mapping of window to pointer
remove(Window w)110     bool remove(Window w) {
111         return YAnyContext::remove(w);
112     }
113 };
114 
115 class YFrameClient;
116 class YFrameWindow;
117 class YWindow;
118 
119 extern YContext<YFrameClient> clientContext;
120 extern YContext<YFrameWindow> frameContext;
121 extern YContext<YWindow> windowContext;
122 
123 #endif
124 
125 // vim: set sw=4 ts=4 et:
126