20 #define __STDCPP_WANT_MATH_SPEC_FUNCS__ 0 22 #define _USE_MATH_DEFINES 23 #include <arpa/inet.h> 27 #include <netinet/in.h> 32 #include <sys/ioctl.h> 48 #include "pedigree/native/graphics/Graphics.h" 49 #include "pedigree/native/input/Input.h" 51 #include <cairo/cairo-ft.h> 52 #include <cairo/cairo.h> 54 #include <pango/pangocairo.h> 56 #include <pedigree_fb.h> 67 #define DEBUG_REDRAWS 0 71 Window *g_pFocusWindow = 0;
73 uint8_t *g_pBackbuffer = 0;
75 std::map<uint64_t, Window *> *g_Windows;
77 std::set<WObject *> g_PendingWindows;
83 int g_iControlPipe[2] = {0};
85 std::string g_StatusField =
"";
87 std::queue<Input::InputNotification> g_InputQueue;
92 ssize_t g_nHeight = 0;
94 ssize_t g_CursorX = 0, g_LastCursorX = 0;
95 ssize_t g_CursorY = 0, g_LastCursorY = 0;
96 bool g_bCursorUpdate =
false;
100 #define ALT_KEY (1ULL << 60) 101 #define SHIFT_KEY (1ULL << 61) 102 #define CTRL_KEY (1ULL << 62) 103 #define SPECIAL_KEY (1ULL << 63) 107 #define CLIENT_DEFAULT "./tui" 109 #define CLIENT_DEFAULT "/applications/TUI" 112 #define TEXTONLY_DEFAULT "/applications/ttyterm" 115 #define DEJAVU_FONT "/usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf" 117 #define DEJAVU_FONT "/system/fonts/DejaVuSansMono.ttf" 124 #undef WINMAN_FORK_WRAPPER 126 #define WINMAN_FORK_WRAPPER 1 134 klog(LOG_CRIT,
"winman: fork failed: %s\n", strerror(errno));
141 close(g_iControlPipe[0]);
142 close(g_iControlPipe[1]);
145 execl(CLIENT_DEFAULT, CLIENT_DEFAULT, NULL);
152 static unsigned int frames = 0;
153 static unsigned int start_time = 0;
156 gettimeofday(&now, NULL);
160 start_time = now.tv_sec;
162 else if (now.tv_sec - start_time >= 5)
164 float seconds = now.tv_sec - start_time;
165 float fps = frames / seconds;
167 LOG_INFO,
"%d frames in %3.1f seconds = %6.3f FPS", frames, seconds,
169 start_time = now.tv_sec;
174 void handleDestroy(
Window *pWindow)
176 Container *myParent = pWindow->getParent();
195 siblingObject = myParent->
getLeft(pWindow);
198 siblingObject = myParent->
getRight(pWindow);
202 siblingObject = myParent->
getUp(pWindow);
206 siblingObject = myParent->
getDown(pWindow);
221 myParent = pContainer;
227 while (siblingObject->getType() == WObject::Container)
230 siblingObject = pContainer->getFocusWindow();
233 if (siblingObject->getType() == WObject::Window)
235 newFocus =
static_cast<Window *
>(siblingObject);
240 g_PendingWindows.insert(myParent);
243 if (g_pFocusWindow == pWindow)
245 g_pFocusWindow = newFocus;
249 g_PendingWindows.insert(newFocus);
258 klog(LOG_INFO,
"winman: no new focus window, terminating");
259 assert(g_Windows->size() <= 1);
264 void handleMessage(
char *messageData,
struct sockaddr *src, socklen_t slen)
266 bool bResult =
false;
277 char *responseData =
new char[totalSize];
278 memset(responseData, 0, totalSize);
283 pParent = g_pFocusWindow->getParent();
288 struct sockaddr_un *sun =
new struct sockaddr_un;
289 *sun = *((
struct sockaddr_un *) src);
291 std::string newTitle(pCreate->
title);
293 pWinMan->
widgetHandle, g_iSocket, (
struct sockaddr *) sun, slen,
295 pWindow->setTitle(newTitle);
297 g_PendingWindows.insert(pWindow);
301 g_pFocusWindow->nofocus();
303 g_pFocusWindow = pWindow;
314 g_Windows->insert(std::make_pair(pWinMan->
widgetHandle, pWindow));
316 pWindow->sendMessage(responseData, totalSize);
318 delete[] responseData;
320 else if (pWinMan->
messageCode == LibUiProtocol::Sync)
322 std::map<uint64_t, Window *>::iterator it =
324 if (it != g_Windows->end())
326 Window *pWindow = it->second;
327 char *responseData =
new char[totalSize];
328 memset(responseData, 0, totalSize);
338 pWindow->sendMessage(responseData, totalSize);
340 delete[] responseData;
343 else if (pWinMan->
messageCode == LibUiProtocol::RequestRedraw)
349 pRedrawMsg->x, pRedrawMsg->y, pRedrawMsg->width,
352 std::map<uint64_t, Window *>::iterator it =
354 if (it != g_Windows->end())
356 Window *pWindow = it->second;
357 pWindow->setDirty(dirty);
358 g_PendingWindows.insert(pWindow);
361 else if (pWinMan->
messageCode == LibUiProtocol::Destroy)
363 std::map<uint64_t, Window *>::iterator it =
365 if (it != g_Windows->end())
367 Window *pWindow = it->second;
369 g_Windows->erase(it);
370 handleDestroy(pWindow);
372 char *responseData =
new char[totalSize];
373 memset(responseData, 0, totalSize);
382 pWindow->sendMessage(responseData, totalSize);
384 delete[] responseData;
389 else if (pWinMan->
messageCode == LibUiProtocol::Nothing)
393 else if (pWinMan->
messageCode == LibUiProtocol::SetTitle)
399 std::map<uint64_t, Window *>::iterator it =
401 if (it != g_Windows->end())
403 Window *pWindow = it->second;
404 pWindow->setTitle(std::string(pTitleMsg->newTitle));
405 g_PendingWindows.insert(pWindow);
410 klog(LOG_INFO,
"winman: unhandled message type");
414 void checkForMessages()
417 bool bTerminate =
false;
420 int result = SDL_PollEvent(&event);
426 if (event.key.keysym.sym == SDLK_ESCAPE)
431 memset(¬e, 0,
sizeof(note));
432 note.type = Input::Key;
433 if (event.key.keysym.mod & KMOD_SHIFT)
434 note.data.key.key |= SHIFT_KEY;
435 if (event.key.keysym.mod & KMOD_ALT)
436 note.data.key.key |= ALT_KEY;
437 if (event.key.keysym.mod & KMOD_CTRL)
438 note.data.key.key |= CTRL_KEY;
440 bool bSpecial =
false;
441 if (event.key.keysym.sym == SDLK_LEFT)
443 memcpy(¬e.data.key.key,
"left", 4);
446 else if (event.key.keysym.sym == SDLK_RIGHT)
448 memcpy(¬e.data.key.key,
"righ", 4);
451 else if (event.key.keysym.sym == SDLK_UP)
453 memcpy(¬e.data.key.key,
"up", 2);
456 else if (event.key.keysym.sym == SDLK_DOWN)
458 memcpy(¬e.data.key.key,
"down", 4);
463 note.data.key.key |= SPECIAL_KEY;
465 note.data.key.key |=
event.key.keysym.sym;
469 if (event.key.keysym.sym != SDLK_LALT &&
470 event.key.keysym.sym != SDLK_RALT &&
471 event.key.keysym.sym != SDLK_LSHIFT &&
472 event.key.keysym.sym != SDLK_RSHIFT &&
473 event.key.keysym.sym != SDLK_LCTRL &&
474 event.key.keysym.sym != SDLK_RCTRL)
476 if (note.data.key.key & SHIFT_KEY)
478 char c = note.data.key.key & 0xFF;
479 note.data.key.key &= ~0xFFFFFFFFUl;
482 note.data.key.key |= toupper(c);
486 note.data.key.key = c - 0x10;
489 queueInputCallback(note);
513 FD_SET(g_iSocket, &fds);
514 FD_SET(g_iControlPipe[0], &fds);
515 int nMax = std::max(g_iSocket, g_iControlPipe[0]);
517 struct timeval tv = {0, 0};
519 struct timeval *timeout = 0;
525 int ret = select(nMax + 1, &fds, 0, 0, timeout);
528 if (FD_ISSET(g_iSocket, &fds))
534 struct sockaddr_un saddr;
535 socklen_t slen =
sizeof(saddr);
536 ssize_t sz = recvfrom(
537 g_iSocket, msg, 4096, 0, (
struct sockaddr *) &saddr, &slen);
541 handleMessage(msg, (
struct sockaddr *) &saddr, slen);
545 if (FD_ISSET(g_iControlPipe[0], &fds))
550 ssize_t bytes = read(g_iControlPipe[0], buf, 1);
553 if ((bytes > 0) && (!g_InputQueue.empty()))
558 queueInputCallback(n);
582 klog(LOG_INFO,
"winman: system input (type=%d)", note.type);
583 static bool bResize =
false;
585 bool bHandled =
false;
586 if (note.type & Input::Key)
588 uint64_t c = note.data.key.key;
590 ActualKey realKey = None;
594 uint32_t k = c & 0xFFFFFFFFULL;
596 memcpy(str, reinterpret_cast<char *>(&k), 4);
599 if (!strcmp(str,
"left"))
603 else if (!strcmp(str,
"righ"))
607 else if (!strcmp(str,
"up"))
611 else if (!strcmp(str,
"down"))
618 if ((c & ALT_KEY) && (g_pFocusWindow != 0))
620 bool bShift = (c & SHIFT_KEY);
623 LOG_INFO,
"ALT-%d [%x%x] %c", (uint32_t) c,
624 (uint32_t)(c >> 32ULL), (uint32_t) c, (
char) c);
627 Container *focusParent = g_pFocusWindow->getParent();
634 klog(LOG_INFO,
"winman: retiling");
635 g_pRootContainer->
retile();
642 if (focusParent == g_pRootContainer)
647 LOG_INFO,
"winman: can't (yet) terminate only " 648 "child of root container!");
657 char *buffer =
new char[totalSize];
658 memset(buffer, 0, totalSize);
668 g_pFocusWindow->sendMessage(buffer, totalSize);
676 else if (c ==
'\n' || c ==
'\r')
682 else if ((c ==
'v') || (c ==
'h'))
684 ::Container::Layout layout;
687 layout = Container::Stacked;
691 layout = Container::SideBySide;
695 layout = Container::SideBySide;
702 focusParent->setLayout(layout);
704 else if (focusParent->getLayout() != layout)
707 pNewContainer->
addChild(g_pFocusWindow,
true);
708 g_pFocusWindow->setParent(pNewContainer);
710 focusParent->
replaceChild(g_pFocusWindow, pNewContainer);
712 pNewContainer->setLayout(layout);
723 g_StatusField =
"<resize mode>";
728 else if (realKey != None)
732 sibling = focusParent->
getLeft(g_pFocusWindow);
734 else if (realKey == Up)
736 sibling = focusParent->
getUp(g_pFocusWindow);
738 else if (realKey == Down)
740 sibling = focusParent->
getDown(g_pFocusWindow);
742 else if (realKey == Right)
744 sibling = focusParent->
getRight(g_pFocusWindow);
750 while (sibling->getType() == WObject::Container)
754 sibling = pContainer->getFocusWindow();
757 if (sibling->getType() == WObject::Window)
759 newFocus =
static_cast<Window *
>(sibling);
770 g_PendingWindows.insert(g_pFocusWindow);
771 g_pFocusWindow->nofocus();
774 g_PendingWindows.insert(newFocus);
776 g_pFocusWindow = newFocus;
777 g_pFocusWindow->focus();
781 if ((!bHandled) && bResize && (g_pFocusWindow))
786 Container *focusParent = g_pFocusWindow->getParent();
796 else if (realKey == Left)
798 sibling = focusParent->
getLeft(g_pFocusWindow);
801 sibling->resize(-10, 0);
804 else if (realKey == Right)
806 sibling = focusParent->
getRight(g_pFocusWindow);
809 g_pFocusWindow->resize(10, 0);
812 else if (realKey == Up)
814 sibling = focusParent->
getUp(g_pFocusWindow);
817 sibling->resize(0, -10);
820 else if (realKey == Down)
822 sibling = focusParent->
getDown(g_pFocusWindow);
825 g_pFocusWindow->resize(0, 10);
835 g_PendingWindows.insert(sibling);
836 g_PendingWindows.insert(g_pFocusWindow);
841 if (note.type & Input::Mouse)
846 g_CursorX += note.data.pointy.relx;
847 g_CursorY -= note.data.pointy.rely;
854 if (g_CursorX >= g_nWidth)
855 g_CursorX = g_nWidth - 1;
856 if (g_CursorY >= g_nHeight)
857 g_CursorY = g_nHeight - 1;
860 LOG_INFO,
"Cursor update %zd, %zd [rel %zd %zd]", g_CursorX,
861 g_CursorY, note.data.pointy.relx, note.data.pointy.rely);
864 g_bCursorUpdate =
true;
867 if ((!bHandled) && (g_pFocusWindow))
871 if (note.type & Input::Key)
873 else if (note.type & Input::RawKey)
876 char *buffer =
new char[totalSize];
877 memset(buffer, 0, totalSize);
882 pHeader->
messageSize = totalSize -
sizeof(*pHeader);
883 pHeader->isResponse =
false;
885 if (note.type & Input::Key)
887 pHeader->messageCode = LibUiProtocol::KeyEvent;
892 pKeyEvent->state = LibUiProtocol::Up;
893 pKeyEvent->key = note.data.key.key;
895 g_pFocusWindow->sendMessage(buffer, totalSize);
897 else if (note.type & Input::RawKey)
899 pHeader->messageCode = LibUiProtocol::RawKeyEvent;
904 pKeyEvent->state = note.data.rawkey.keyUp ? LibUiProtocol::Up :
906 pKeyEvent->scancode = note.data.rawkey.scancode;
908 g_pFocusWindow->sendMessage(buffer, totalSize);
919 g_InputQueue.push(n);
925 r = write(g_iControlPipe[1],
"w", 1);
931 klog(LOG_INFO,
"SIGCHLD");
933 pid_t pid = waitpid(-1, &status, WNOHANG);
936 klog(LOG_ALERT,
"SIGCHLD handler called but no children to reap.");
940 if (WIFEXITED(status))
942 int exit_status = WEXITSTATUS(status);
943 klog(LOG_INFO,
"Child %d exited with status %d.", pid, exit_status);
945 else if (WIFSIGNALED(status))
947 int term_signal = WTERMSIG(status);
948 klog(LOG_INFO,
"Child %d terminated with signal %d.", pid, term_signal);
952 klog(LOG_INFO,
"Child %d terminated for an unknown reason.", pid);
956 for (std::map<uint64_t, Window *>::iterator it = g_Windows->begin();
957 it != g_Windows->end();)
959 uint64_t handle = it->first;
960 pid_t window_pid = (handle >> 32ULL) & 0xFFFFFFFFU;
961 klog(LOG_INFO,
"%d vs %d", window_pid, pid);
962 if (window_pid == pid)
964 klog(LOG_INFO,
"Found a child window for the terminated child.");
965 handleDestroy(it->second);
968 g_Windows->erase(it++);
977 void infoPanel(cairo_t *cr)
981 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
983 cairo_set_source_rgba(cr, 0.2, 0.2, 0.2, 0.8);
984 cairo_rectangle(cr, 0, g_nHeight - 24, g_nWidth, 24);
987 PangoLayout *layout = pango_cairo_create_layout(cr);
988 PangoFontDescription *desc =
989 pango_font_description_from_string(WINMAN_PANGO_FONT);
991 pango_layout_set_markup(layout,
"The Pedigree Operating System", -1);
993 pango_layout_set_font_description(layout, desc);
994 pango_font_description_free(desc);
996 cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
997 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
998 cairo_move_to(cr, 3, (g_nHeight - 24) + 3);
999 pango_cairo_show_layout(cr, layout);
1001 if (g_StatusField.length())
1003 gchar *safe_markup = g_markup_escape_text(g_StatusField.c_str(), -1);
1004 pango_layout_set_markup(layout, safe_markup, -1);
1005 int width = 0, height = 0;
1006 pango_layout_get_size(layout, &width, &height);
1008 cairo_move_to(cr, g_nWidth - 3 - width, (g_nHeight - 24) + 3);
1009 pango_cairo_show_layout(cr, layout);
1010 g_StatusField.clear();
1011 g_free(safe_markup);
1014 g_object_unref(layout);
1018 int main(
int argc,
char *argv[])
1021 openlog(
"winman", LOG_PID, LOG_USER);
1024 klog(LOG_INFO,
"winman: starting up...");
1025 fprintf(stderr,
"I am PID %d\n", getpid());
1029 int fd = open(
"runtimeĀ»/winman.lck", O_WRONLY | O_EXCL | O_CREAT, 0500);
1032 fprintf(stderr,
"winman: lock file exists, terminating.\n");
1033 return EXIT_FAILURE;
1040 fprintf(stderr,
"winman: framebuffer initialisation failed\n");
1041 return EXIT_FAILURE;
1049 #ifdef WINMAN_FORK_WRAPPER 1050 pid_t child = fork();
1053 fprintf(stderr,
"winman: could not fork: %s\n", strerror(errno));
1056 else if (child != 0)
1060 waitpid(child, &status, 0);
1064 delete pFramebuffer;
1067 if (WIFEXITED(status))
1070 stderr,
"winman: terminated with status %d\n",
1071 WEXITSTATUS(status));
1073 else if (WIFSIGNALED(status))
1076 stderr,
"winman: terminated by signal %d\n", WTERMSIG(status));
1080 fprintf(stderr,
"winman: terminated by unknown means\n");
1090 int result = pipe(g_iControlPipe);
1094 stderr,
"winman: couldn't create control pipe [%s]\n",
1096 return EXIT_FAILURE;
1100 g_iSocket = socket(AF_UNIX, SOCK_DGRAM, 0);
1105 "error: couldn't create the pedigree-winman IPC endpoint! [%s]",
1107 return EXIT_FAILURE;
1111 struct sockaddr_un bind_addr;
1112 bind_addr.sun_family = AF_UNIX;
1113 memset(bind_addr.sun_path, 0,
sizeof bind_addr.sun_path);
1114 strncpy(bind_addr.sun_path, WINMAN_SOCKET_PATH,
sizeof bind_addr.sun_path);
1115 socklen_t socklen =
sizeof(bind_addr);
1116 result = bind(g_iSocket, (
struct sockaddr *) &bind_addr, socklen);
1120 stderr,
"winman: couldn't bind to %s [%s]\n", WINMAN_SOCKET_PATH,
1122 return EXIT_FAILURE;
1126 if (SDL_Init(SDL_INIT_VIDEO) != 0)
1128 fprintf(stderr,
"winman: SDL initialisation failed.\n");
1129 return EXIT_FAILURE;
1135 result = pFramebuffer->
enterMode(1024, 768, 32);
1139 g_nWidth = pFramebuffer->getWidth();
1140 g_nHeight = pFramebuffer->getHeight();
1142 klog(LOG_INFO,
"Actual mode is %ux%u", g_nWidth, g_nHeight);
1144 cairo_format_t format = pFramebuffer->getFormat();
1146 int stride = cairo_format_stride_for_width(format, g_nWidth);
1150 cairo_surface_t *surface = cairo_image_surface_create_for_data(
1151 (uint8_t *) framebufferVirt, format, g_nWidth, g_nHeight, stride);
1152 cairo_t *cr = cairo_create(surface);
1154 FT_Library font_library;
1156 int e = FT_Init_FreeType(&font_library);
1159 klog(LOG_CRIT,
"error: couldn't initialise Freetype");
1163 e = FT_New_Face(font_library, DEJAVU_FONT, 0, &ft_face);
1166 klog(LOG_CRIT,
"winman: error: couldn't load required font");
1170 cairo_user_data_key_t key;
1171 cairo_font_face_t *font_face;
1173 font_face = cairo_ft_font_face_create_for_ft_face(ft_face, 0);
1174 cairo_font_face_set_user_data(
1175 font_face, &key, ft_face, (cairo_destroy_func_t) FT_Done_Face);
1176 cairo_set_font_face(cr, font_face);
1179 FILE *fp = fopen(
"/system/wallpaper/fields.png",
"rb");
1185 wallpaper =
new Png(
"/system/wallpaper/trees.png");
1186 wallpaper->render(cr, 0, 0, g_nWidth, g_nHeight);
1191 cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
1192 cairo_set_source_rgba(cr, 0, 0, 1.0, 1.0);
1193 cairo_rectangle(cr, 0, 0, g_nWidth, g_nHeight);
1197 g_pRootContainer =
new RootContainer(g_nWidth, g_nHeight - 24);
1201 klog(LOG_INFO,
"winman: entering main loop pid=%d", getpid());
1203 g_Windows =
new std::map<uint64_t, Window *>();
1206 #ifndef TARGET_LINUX 1207 Input::installCallback(
1208 Input::RawKey | Input::Key | Input::Mouse, systemInputCallback);
1212 g_pRootContainer->
render(cr);
1215 cairo_surface_flush(surface);
1216 pFramebuffer->
flush(0, 0, g_nWidth, g_nHeight);
1219 struct sigaction act;
1220 memset(&act, 0,
sizeof(act));
1221 act.sa_handler = sigchld;
1222 sigemptyset(&act.sa_mask);
1223 act.sa_flags = SA_NOCLDSTOP | SA_SIGINFO;
1224 sigaction(SIGCHLD, &act, NULL);
1238 if ((!g_PendingWindows.empty()) || g_StatusField.length() ||
1243 std::set<WObject *>::iterator it = g_PendingWindows.begin();
1244 size_t nDirty = g_StatusField.length() ? 1 : 0;
1245 if (g_bCursorUpdate)
1247 for (; it != g_PendingWindows.end(); ++it)
1250 if ((*it)->getType() == WObject::Window)
1252 pWindow =
static_cast<Window *
>(*it);
1255 if (pWindow && !pWindow->isDirty())
1268 dirty = pWindow->getDirty();
1274 wallpaper->renderPartial(
1275 cr, rt.getX() + dirty.getX(), rt.getY() + dirty.getY(),
1276 0, 0, dirty.getW(), dirty.getH(), g_nWidth, g_nHeight);
1278 cairo_set_source_rgba(cr, 0, 0, 1.0, 1.0);
1280 cr, rt.getX() + dirty.getX(), rt.getY() + dirty.getY(),
1281 dirty.getW(), dirty.getH());
1288 cairo_set_source_rgba(cr, 0, 0, 1.0, 1.0);
1290 cr, rt.getX() + dirty.getX(), rt.getY() + dirty.getY(),
1291 dirty.getW(), dirty.getH());
1293 cairo_stroke_preserve(cr);
1303 rt.getX() + dirty.getX(), rt.getX() + dirty.getY());
1305 rt.getX() + dirty.getX() + dirty.getW(),
1306 rt.getX() + dirty.getY() + dirty.getH());
1310 g_PendingWindows.clear();
1315 renderDirty.reset();
1319 if (g_StatusField.length())
1326 cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
1334 renderDirty.point(g_CursorX, g_CursorY);
1335 renderDirty.point(g_CursorX + 32, g_CursorY + 32);
1338 g_LastCursorX = g_CursorX;
1339 g_LastCursorY = g_CursorY;
1342 g_bCursorUpdate =
false;
1347 cairo_surface_flush(surface);
1350 pFramebuffer->
flush(
1351 renderDirty.getX(), renderDirty.getY(), renderDirty.getWidth(),
1352 renderDirty.getHeight());
1355 renderDirty.reset();
1360 klog(LOG_INFO,
"winman terminating");
1368 delete g_pRootContainer;
1370 cairo_font_face_destroy(font_face);
1372 FT_Done_Face(ft_face);
1373 FT_Done_FreeType(font_library);
1375 cairo_surface_destroy(surface);
1378 delete pFramebuffer;
WObject * getParent() const
void replaceChild(WObject *pChild, WObject *pNewChild)
size_t getChildCount() const
int enterMode(size_t desiredW, size_t desiredH, size_t desiredBpp)
WObject * getRightSibling(const WObject *pChild) const
virtual void yesrefresh()
Refresh context on every reposition.
char title[256]
Initial title for this widget.
WObject * getLeftSibling(const WObject *pChild) const
WObject * getDown(const WObject *obj) const
void addChild(WObject *pChild, bool bNoRetile=false)
handle_t widgetHandle
Handle for the widget being referred to. Zero if no widget.
void flush(size_t x, size_t y, size_t w, size_t h)
size_t messageSize
Size of the data in the message (after this header).
WObject * getRight(const WObject *obj) const
Abstracts the system's framebuffer offering.
void removeChild(WObject *pChild)
virtual void * getFramebuffer()
WObject * getLeft(const WObject *obj) const
MessageIdentifiers messageCode
Code of the message being sent.
virtual void norefresh()
Don't refresh the context on every reposition.
WObject * getUp(const WObject *obj) const
bool isResponse
Whether this message is a response from the window manager or not.