Window.cpp (4143B)
1 #include <blt/namer.h> 2 #include <blt/syscall.h> 3 #include <win/Window.h> 4 #include <win/Canvas.h> 5 #include <win/Event.h> 6 #include <stdio.h> 7 #include "../../srv/window/protocol.h" 8 #include "Connection.h" 9 10 Window::Window(long left, long top, long right, long bottom) 11 : fShowLevel(0), 12 fCanvasList(0) 13 { 14 int windowServerPort; 15 windowServerPort = namer_find ("window_server", 0); 16 if (windowServerPort <= 0) { 17 printf("couldn't connect to window server\n"); 18 return; 19 } 20 21 int localReplyPort = port_create(0, "client_syncport"); 22 fEventPort = port_create(0, "client_eventport"); 23 24 fConnection = new Connection(windowServerPort, localReplyPort); 25 fConnection->WriteInt8(OP_CREATE_WINDOW); 26 fConnection->WriteInt32(0); // Child of root window 27 fConnection->WriteInt32(left); 28 fConnection->WriteInt32(top); 29 fConnection->WriteInt32(right); 30 fConnection->WriteInt32(bottom); 31 fConnection->WriteInt32(fEventPort); 32 fConnection->Flush(); 33 fID = fConnection->ReadInt32(); 34 35 fLock = qsem_create(1); 36 37 thr_create((void*) EventLoop, this, "win_thread"); 38 } 39 40 Window::~Window() 41 { 42 qsem_acquire(fLock); 43 while (fCanvasList) { 44 Canvas *child = fCanvasList; 45 fCanvasList = fCanvasList->fWinListNext; 46 fConnection->WriteInt8(OP_DESTROY_WINDOW); 47 fConnection->WriteInt32(child->fID); 48 fConnection->Flush(); 49 delete child; 50 } 51 52 fConnection->WriteInt8(OP_DESTROY_WINDOW); 53 fConnection->WriteInt32(fID); 54 fConnection->Flush(); 55 delete fConnection; 56 57 qsem_destroy(fLock); 58 } 59 60 61 void Window::MakeFocus() 62 { 63 fConnection->WriteInt8(OP_MAKE_FOCUS); 64 fConnection->WriteInt32(fID); 65 fConnection->Flush(); 66 } 67 68 void Window::Flush() 69 { 70 fConnection->Flush(); 71 } 72 73 void Window::WaitEvent(Event *event) 74 { 75 msg_hdr_t header; 76 header.src = 0; 77 header.dst = fEventPort; 78 header.data = event; 79 header.size = sizeof(Event); 80 old_port_recv(&header); 81 } 82 83 void Window::AddChild(Canvas *child, long left, long top, long right, long bottom) 84 { 85 fConnection->WriteInt8(OP_CREATE_WINDOW); 86 fConnection->WriteInt32(fID); // My child 87 fConnection->WriteInt32(left); 88 fConnection->WriteInt32(top); 89 fConnection->WriteInt32(right); 90 fConnection->WriteInt32(bottom); 91 fConnection->WriteInt32(fEventPort); 92 fConnection->Flush(); 93 child->fID = fConnection->ReadInt32(); 94 child->fWindow = this; 95 child->fLeft = 0; 96 child->fTop = 0; 97 child->fRight = right - left; 98 child->fBottom = bottom - top; 99 child->Show(); 100 101 // Stick window in my canvas list 102 child->fWinListNext = fCanvasList; 103 child->fWinListPrev = &fCanvasList; 104 if (fCanvasList) 105 fCanvasList->fWinListPrev = &child->fWinListNext; 106 107 fCanvasList = child; 108 } 109 110 void Window::RemoveChild(Canvas *child) 111 { 112 Lock(); 113 fConnection->WriteInt8(OP_DESTROY_WINDOW); 114 fConnection->WriteInt32(child->fID); 115 fConnection->Flush(); 116 *child->fWinListPrev = child->fWinListNext; 117 if (child->fWinListNext) 118 child->fWinListNext->fWinListPrev = child->fWinListPrev; 119 120 Unlock(); 121 } 122 123 void Window::Lock() 124 { 125 qsem_acquire(fLock); 126 } 127 128 void Window::Unlock() 129 { 130 qsem_release(fLock); 131 } 132 133 void Window::Hide() 134 { 135 if (--fShowLevel == 0) { 136 fConnection->WriteInt8(OP_HIDE_WINDOW); 137 fConnection->WriteInt32(fID); 138 fConnection->Flush(); 139 } 140 } 141 142 void Window::Show() 143 { 144 if (++fShowLevel == 1) { 145 fConnection->WriteInt8(OP_SHOW_WINDOW); 146 fConnection->WriteInt32(fID); 147 fConnection->Flush(); 148 } 149 } 150 151 Canvas* Window::FindChild(int id) 152 { 153 for (Canvas *canvas = fCanvasList; canvas; canvas = canvas->fWinListNext) 154 if (canvas->fID == id) 155 return canvas; 156 157 return 0; 158 } 159 160 void Window::DispatchEvent(Event *event) 161 { 162 Canvas *canvas = FindChild(event->target); 163 if (canvas) 164 canvas->HandleEvent(event); 165 } 166 167 int Window::EventLoop(void *_window) 168 { 169 Window *window = (Window*) _window; 170 while (true) { 171 Event event; 172 window->WaitEvent(&event); 173 if (event.what == EVT_QUIT) { 174 delete window; 175 os_terminate(0); 176 } 177 178 window->Lock(); 179 window->DispatchEvent(&event); 180 window->Unlock(); 181 } 182 } 183 184 void Window::Quit() 185 { 186 Event event; 187 event.what = EVT_QUIT; 188 event.target = fID; 189 190 msg_hdr_t header; 191 header.src = fEventPort; // May break someday 192 header.dst = fEventPort; 193 header.data = &event; 194 header.size = sizeof(Event); 195 old_port_send(&header); 196 } 197 198