openblt

a hobby OS from the late 90s
git clone http://frotz.net/git/openblt.git
Log | Files | Refs | LICENSE

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