tcp: Fix 64 bit build with debugging features enabled.
[haiku.git] / src / kits / interface / InterfaceDefs.cpp
blob880f786858c022aee7e10df27a3e07fc6297bf44
1 /*
2 * Copyright 2001-2015, Haiku, Inc.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * DarkWyrm <bpmagic@columbus.rr.com>
7 * Caz <turok2@currantbun.com>
8 * Axel Dörfler, axeld@pinc-software.de
9 * Michael Lotz <mmlr@mlotz.ch>
10 * Wim van der Meer <WPJvanderMeer@gmail.com>
14 /*! Global functions and variables for the Interface Kit */
17 #include <InterfaceDefs.h>
19 #include <new>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
24 #include <Bitmap.h>
25 #include <Clipboard.h>
26 #include <ControlLook.h>
27 #include <Font.h>
28 #include <Menu.h>
29 #include <Point.h>
30 #include <Roster.h>
31 #include <Screen.h>
32 #include <ScrollBar.h>
33 #include <String.h>
34 #include <TextView.h>
35 #include <Window.h>
37 #include <ApplicationPrivate.h>
38 #include <AppServerLink.h>
39 #include <ColorConversion.h>
40 #include <DecorInfo.h>
41 #include <DefaultColors.h>
42 #include <InputServerTypes.h>
43 #include <input_globals.h>
44 #include <InterfacePrivate.h>
45 #include <MenuPrivate.h>
46 #include <pr_server.h>
47 #include <ServerProtocol.h>
48 #include <ServerReadOnlyMemory.h>
49 #include <truncate_string.h>
50 #include <utf8_functions.h>
51 #include <WidthBuffer.h>
52 #include <WindowInfo.h>
55 using namespace BPrivate;
57 // some other weird struct exported by BeOS, it's not initialized, though
58 struct general_ui_info {
59 rgb_color background_color;
60 rgb_color mark_color;
61 rgb_color highlight_color;
62 bool color_frame;
63 rgb_color window_frame_color;
66 struct general_ui_info general_info;
68 menu_info *_menu_info_ptr_;
70 extern "C" const char B_NOTIFICATION_SENDER[] = "be:sender";
72 static const rgb_color _kDefaultColors[kColorWhichCount] = {
73 {216, 216, 216, 255}, // B_PANEL_BACKGROUND_COLOR
74 {216, 216, 216, 255}, // B_MENU_BACKGROUND_COLOR
75 {255, 203, 0, 255}, // B_WINDOW_TAB_COLOR
76 {0, 0, 229, 255}, // B_KEYBOARD_NAVIGATION_COLOR
77 {51, 102, 152, 255}, // B_DESKTOP_COLOR
78 {153, 153, 153, 255}, // B_MENU_SELECTED_BACKGROUND_COLOR
79 {0, 0, 0, 255}, // B_MENU_ITEM_TEXT_COLOR
80 {0, 0, 0, 255}, // B_MENU_SELECTED_ITEM_TEXT_COLOR
81 {0, 0, 0, 255}, // B_MENU_SELECTED_BORDER_COLOR
82 {0, 0, 0, 255}, // B_PANEL_TEXT_COLOR
83 {255, 255, 255, 255}, // B_DOCUMENT_BACKGROUND_COLOR
84 {0, 0, 0, 255}, // B_DOCUMENT_TEXT_COLOR
85 {245, 245, 245, 255}, // B_CONTROL_BACKGROUND_COLOR
86 {0, 0, 0, 255}, // B_CONTROL_TEXT_COLOR
87 {0, 0, 0, 255}, // B_CONTROL_BORDER_COLOR
88 {102, 152, 203, 255}, // B_CONTROL_HIGHLIGHT_COLOR
89 {0, 0, 0, 255}, // B_NAVIGATION_PULSE_COLOR
90 {255, 255, 255, 255}, // B_SHINE_COLOR
91 {0, 0, 0, 255}, // B_SHADOW_COLOR
92 {255, 255, 216, 255}, // B_TOOLTIP_BACKGROUND_COLOR
93 {0, 0, 0, 255}, // B_TOOLTIP_TEXT_COLOR
94 {0, 0, 0, 255}, // B_WINDOW_TEXT_COLOR
95 {232, 232, 232, 255}, // B_WINDOW_INACTIVE_TAB_COLOR
96 {80, 80, 80, 255}, // B_WINDOW_INACTIVE_TEXT_COLOR
97 {224, 224, 224, 255}, // B_WINDOW_BORDER_COLOR
98 {232, 232, 232, 255}, // B_WINDOW_INACTIVE_BORDER_COLOR
99 {27, 82, 140, 255}, // B_CONTROL_MARK_COLOR
100 {255, 255, 255, 255}, // B_LIST_BACKGROUND_COLOR
101 {190, 190, 190, 255}, // B_LIST_SELECTED_BACKGROUND_COLOR
102 {0, 0, 0, 255}, // B_LIST_ITEM_TEXT_COLOR
103 {0, 0, 0, 255}, // B_LIST_SELECTED_ITEM_TEXT_COLOR
104 {216, 216, 216, 255}, // B_SCROLL_BAR_THUMB_COLOR
105 // 100...
106 {46, 204, 64, 255}, // B_SUCCESS_COLOR
107 {255, 65, 54, 255}, // B_FAILURE_COLOR
110 const rgb_color* BPrivate::kDefaultColors = &_kDefaultColors[0];
113 namespace BPrivate {
116 /*! Fills the \a width, \a height, and \a colorSpace parameters according
117 to the window screen's mode.
118 Returns \c true if the mode is known.
120 bool
121 get_mode_parameter(uint32 mode, int32& width, int32& height,
122 uint32& colorSpace)
124 switch (mode) {
125 case B_8_BIT_640x480:
126 case B_8_BIT_800x600:
127 case B_8_BIT_1024x768:
128 case B_8_BIT_1152x900:
129 case B_8_BIT_1280x1024:
130 case B_8_BIT_1600x1200:
131 colorSpace = B_CMAP8;
132 break;
134 case B_15_BIT_640x480:
135 case B_15_BIT_800x600:
136 case B_15_BIT_1024x768:
137 case B_15_BIT_1152x900:
138 case B_15_BIT_1280x1024:
139 case B_15_BIT_1600x1200:
140 colorSpace = B_RGB15;
141 break;
143 case B_16_BIT_640x480:
144 case B_16_BIT_800x600:
145 case B_16_BIT_1024x768:
146 case B_16_BIT_1152x900:
147 case B_16_BIT_1280x1024:
148 case B_16_BIT_1600x1200:
149 colorSpace = B_RGB16;
150 break;
152 case B_32_BIT_640x480:
153 case B_32_BIT_800x600:
154 case B_32_BIT_1024x768:
155 case B_32_BIT_1152x900:
156 case B_32_BIT_1280x1024:
157 case B_32_BIT_1600x1200:
158 colorSpace = B_RGB32;
159 break;
161 default:
162 return false;
165 switch (mode) {
166 case B_8_BIT_640x480:
167 case B_15_BIT_640x480:
168 case B_16_BIT_640x480:
169 case B_32_BIT_640x480:
170 width = 640; height = 480;
171 break;
173 case B_8_BIT_800x600:
174 case B_15_BIT_800x600:
175 case B_16_BIT_800x600:
176 case B_32_BIT_800x600:
177 width = 800; height = 600;
178 break;
180 case B_8_BIT_1024x768:
181 case B_15_BIT_1024x768:
182 case B_16_BIT_1024x768:
183 case B_32_BIT_1024x768:
184 width = 1024; height = 768;
185 break;
187 case B_8_BIT_1152x900:
188 case B_15_BIT_1152x900:
189 case B_16_BIT_1152x900:
190 case B_32_BIT_1152x900:
191 width = 1152; height = 900;
192 break;
194 case B_8_BIT_1280x1024:
195 case B_15_BIT_1280x1024:
196 case B_16_BIT_1280x1024:
197 case B_32_BIT_1280x1024:
198 width = 1280; height = 1024;
199 break;
201 case B_8_BIT_1600x1200:
202 case B_15_BIT_1600x1200:
203 case B_16_BIT_1600x1200:
204 case B_32_BIT_1600x1200:
205 width = 1600; height = 1200;
206 break;
209 return true;
213 void
214 get_workspaces_layout(uint32* _columns, uint32* _rows)
216 int32 columns = 1;
217 int32 rows = 1;
219 BPrivate::AppServerLink link;
220 link.StartMessage(AS_GET_WORKSPACE_LAYOUT);
222 status_t status;
223 if (link.FlushWithReply(status) == B_OK && status == B_OK) {
224 link.Read<int32>(&columns);
225 link.Read<int32>(&rows);
228 if (_columns != NULL)
229 *_columns = columns;
230 if (_rows != NULL)
231 *_rows = rows;
235 void
236 set_workspaces_layout(uint32 columns, uint32 rows)
238 if (columns < 1 || rows < 1)
239 return;
241 BPrivate::AppServerLink link;
242 link.StartMessage(AS_SET_WORKSPACE_LAYOUT);
243 link.Attach<int32>(columns);
244 link.Attach<int32>(rows);
245 link.Flush();
249 } // namespace BPrivate
252 void
253 set_subpixel_antialiasing(bool subpix)
255 BPrivate::AppServerLink link;
257 link.StartMessage(AS_SET_SUBPIXEL_ANTIALIASING);
258 link.Attach<bool>(subpix);
259 link.Flush();
263 status_t
264 get_subpixel_antialiasing(bool* subpix)
266 BPrivate::AppServerLink link;
268 link.StartMessage(AS_GET_SUBPIXEL_ANTIALIASING);
269 int32 status = B_ERROR;
270 if (link.FlushWithReply(status) != B_OK || status < B_OK)
271 return status;
272 link.Read<bool>(subpix);
273 return B_OK;
277 void
278 set_hinting_mode(uint8 hinting)
280 BPrivate::AppServerLink link;
282 link.StartMessage(AS_SET_HINTING);
283 link.Attach<uint8>(hinting);
284 link.Flush();
288 status_t
289 get_hinting_mode(uint8* hinting)
291 BPrivate::AppServerLink link;
293 link.StartMessage(AS_GET_HINTING);
294 int32 status = B_ERROR;
295 if (link.FlushWithReply(status) != B_OK || status < B_OK)
296 return status;
297 link.Read<uint8>(hinting);
298 return B_OK;
302 void
303 set_average_weight(uint8 averageWeight)
305 BPrivate::AppServerLink link;
307 link.StartMessage(AS_SET_SUBPIXEL_AVERAGE_WEIGHT);
308 link.Attach<uint8>(averageWeight);
309 link.Flush();
313 status_t
314 get_average_weight(uint8* averageWeight)
316 BPrivate::AppServerLink link;
318 link.StartMessage(AS_GET_SUBPIXEL_AVERAGE_WEIGHT);
319 int32 status = B_ERROR;
320 if (link.FlushWithReply(status) != B_OK || status < B_OK)
321 return status;
322 link.Read<uint8>(averageWeight);
323 return B_OK;
327 void
328 set_is_subpixel_ordering_regular(bool subpixelOrdering)
330 BPrivate::AppServerLink link;
332 link.StartMessage(AS_SET_SUBPIXEL_ORDERING);
333 link.Attach<bool>(subpixelOrdering);
334 link.Flush();
338 status_t
339 get_is_subpixel_ordering_regular(bool* subpixelOrdering)
341 BPrivate::AppServerLink link;
343 link.StartMessage(AS_GET_SUBPIXEL_ORDERING);
344 int32 status = B_ERROR;
345 if (link.FlushWithReply(status) != B_OK || status < B_OK)
346 return status;
347 link.Read<bool>(subpixelOrdering);
348 return B_OK;
352 const color_map *
353 system_colors()
355 return BScreen(B_MAIN_SCREEN_ID).ColorMap();
359 status_t
360 set_screen_space(int32 index, uint32 space, bool stick)
362 int32 width;
363 int32 height;
364 uint32 depth;
365 if (!BPrivate::get_mode_parameter(space, width, height, depth))
366 return B_BAD_VALUE;
368 BScreen screen(B_MAIN_SCREEN_ID);
369 display_mode mode;
371 // TODO: What about refresh rate ?
372 // currently we get it from the current video mode, but
373 // this might be not so wise.
374 status_t status = screen.GetMode(index, &mode);
375 if (status < B_OK)
376 return status;
378 mode.virtual_width = width;
379 mode.virtual_height = height;
380 mode.space = depth;
382 return screen.SetMode(index, &mode, stick);
386 status_t
387 get_scroll_bar_info(scroll_bar_info *info)
389 if (info == NULL)
390 return B_BAD_VALUE;
392 BPrivate::AppServerLink link;
393 link.StartMessage(AS_GET_SCROLLBAR_INFO);
395 int32 code;
396 if (link.FlushWithReply(code) == B_OK
397 && code == B_OK) {
398 link.Read<scroll_bar_info>(info);
399 return B_OK;
402 return B_ERROR;
406 status_t
407 set_scroll_bar_info(scroll_bar_info *info)
409 if (info == NULL)
410 return B_BAD_VALUE;
412 BPrivate::AppServerLink link;
413 int32 code;
415 link.StartMessage(AS_SET_SCROLLBAR_INFO);
416 link.Attach<scroll_bar_info>(*info);
418 if (link.FlushWithReply(code) == B_OK
419 && code == B_OK)
420 return B_OK;
422 return B_ERROR;
426 status_t
427 get_mouse_type(int32 *type)
429 BMessage command(IS_GET_MOUSE_TYPE);
430 BMessage reply;
432 status_t err = _control_input_server_(&command, &reply);
433 if (err != B_OK)
434 return err;
435 return reply.FindInt32("mouse_type", type);
439 status_t
440 set_mouse_type(int32 type)
442 BMessage command(IS_SET_MOUSE_TYPE);
443 BMessage reply;
445 status_t err = command.AddInt32("mouse_type", type);
446 if (err != B_OK)
447 return err;
448 return _control_input_server_(&command, &reply);
452 status_t
453 get_mouse_map(mouse_map *map)
455 BMessage command(IS_GET_MOUSE_MAP);
456 BMessage reply;
457 const void *data = 0;
458 ssize_t count;
460 status_t err = _control_input_server_(&command, &reply);
461 if (err == B_OK)
462 err = reply.FindData("mousemap", B_RAW_TYPE, &data, &count);
463 if (err != B_OK)
464 return err;
466 memcpy(map, data, count);
468 return B_OK;
472 status_t
473 set_mouse_map(mouse_map *map)
475 BMessage command(IS_SET_MOUSE_MAP);
476 BMessage reply;
478 status_t err = command.AddData("mousemap", B_RAW_TYPE, map,
479 sizeof(mouse_map));
480 if (err != B_OK)
481 return err;
482 return _control_input_server_(&command, &reply);
486 status_t
487 get_click_speed(bigtime_t *speed)
489 BMessage command(IS_GET_CLICK_SPEED);
490 BMessage reply;
492 status_t err = _control_input_server_(&command, &reply);
493 if (err != B_OK)
494 return err;
496 if (reply.FindInt64("speed", speed) != B_OK)
497 *speed = 500000;
499 return B_OK;
503 status_t
504 set_click_speed(bigtime_t speed)
506 BMessage command(IS_SET_CLICK_SPEED);
507 BMessage reply;
508 command.AddInt64("speed", speed);
509 return _control_input_server_(&command, &reply);
513 status_t
514 get_mouse_speed(int32 *speed)
516 BMessage command(IS_GET_MOUSE_SPEED);
517 BMessage reply;
519 status_t err = _control_input_server_(&command, &reply);
520 if (err != B_OK)
521 return err;
523 if (reply.FindInt32("speed", speed) != B_OK)
524 *speed = 65536;
526 return B_OK;
530 status_t
531 set_mouse_speed(int32 speed)
533 BMessage command(IS_SET_MOUSE_SPEED);
534 BMessage reply;
535 command.AddInt32("speed", speed);
536 return _control_input_server_(&command, &reply);
540 status_t
541 get_mouse_acceleration(int32 *speed)
543 BMessage command(IS_GET_MOUSE_ACCELERATION);
544 BMessage reply;
546 _control_input_server_(&command, &reply);
548 if (reply.FindInt32("speed", speed) != B_OK)
549 *speed = 65536;
551 return B_OK;
555 status_t
556 set_mouse_acceleration(int32 speed)
558 BMessage command(IS_SET_MOUSE_ACCELERATION);
559 BMessage reply;
560 command.AddInt32("speed", speed);
561 return _control_input_server_(&command, &reply);
565 status_t
566 get_key_repeat_rate(int32 *rate)
568 BMessage command(IS_GET_KEY_REPEAT_RATE);
569 BMessage reply;
571 _control_input_server_(&command, &reply);
573 if (reply.FindInt32("rate", rate) != B_OK)
574 *rate = 250000;
576 return B_OK;
580 status_t
581 set_key_repeat_rate(int32 rate)
583 BMessage command(IS_SET_KEY_REPEAT_RATE);
584 BMessage reply;
585 command.AddInt32("rate", rate);
586 return _control_input_server_(&command, &reply);
590 status_t
591 get_key_repeat_delay(bigtime_t *delay)
593 BMessage command(IS_GET_KEY_REPEAT_DELAY);
594 BMessage reply;
596 _control_input_server_(&command, &reply);
598 if (reply.FindInt64("delay", delay) != B_OK)
599 *delay = 200;
601 return B_OK;
605 status_t
606 set_key_repeat_delay(bigtime_t delay)
608 BMessage command(IS_SET_KEY_REPEAT_DELAY);
609 BMessage reply;
610 command.AddInt64("delay", delay);
611 return _control_input_server_(&command, &reply);
615 uint32
616 modifiers()
618 BMessage command(IS_GET_MODIFIERS);
619 BMessage reply;
620 int32 err, modifier;
622 _control_input_server_(&command, &reply);
624 if (reply.FindInt32("status", &err) != B_OK)
625 return 0;
627 if (reply.FindInt32("modifiers", &modifier) != B_OK)
628 return 0;
630 return modifier;
634 status_t
635 get_key_info(key_info *info)
637 BMessage command(IS_GET_KEY_INFO);
638 BMessage reply;
639 const void *data = 0;
640 int32 err;
641 ssize_t count;
643 _control_input_server_(&command, &reply);
645 if (reply.FindInt32("status", &err) != B_OK)
646 return B_ERROR;
648 if (reply.FindData("key_info", B_ANY_TYPE, &data, &count) != B_OK)
649 return B_ERROR;
651 memcpy(info, data, count);
652 return B_OK;
656 void
657 get_key_map(key_map **map, char **key_buffer)
659 _get_key_map(map, key_buffer, NULL);
663 void
664 _get_key_map(key_map **map, char **key_buffer, ssize_t *key_buffer_size)
666 BMessage command(IS_GET_KEY_MAP);
667 BMessage reply;
668 ssize_t map_count, key_count;
669 const void *map_array = 0, *key_array = 0;
670 if (key_buffer_size == NULL)
671 key_buffer_size = &key_count;
673 _control_input_server_(&command, &reply);
675 if (reply.FindData("keymap", B_ANY_TYPE, &map_array, &map_count) != B_OK) {
676 *map = 0; *key_buffer = 0;
677 return;
680 if (reply.FindData("key_buffer", B_ANY_TYPE, &key_array, key_buffer_size)
681 != B_OK) {
682 *map = 0; *key_buffer = 0;
683 return;
686 *map = (key_map *)malloc(map_count);
687 memcpy(*map, map_array, map_count);
688 *key_buffer = (char *)malloc(*key_buffer_size);
689 memcpy(*key_buffer, key_array, *key_buffer_size);
693 status_t
694 get_keyboard_id(uint16 *id)
696 BMessage command(IS_GET_KEYBOARD_ID);
697 BMessage reply;
698 uint16 kid;
700 _control_input_server_(&command, &reply);
702 status_t err = reply.FindInt16("id", (int16 *)&kid);
703 if (err != B_OK)
704 return err;
705 *id = kid;
707 return B_OK;
711 status_t
712 get_modifier_key(uint32 modifier, uint32 *key)
714 BMessage command(IS_GET_MODIFIER_KEY);
715 BMessage reply;
716 uint32 rkey;
718 command.AddInt32("modifier", modifier);
719 _control_input_server_(&command, &reply);
721 status_t err = reply.FindInt32("key", (int32 *) &rkey);
722 if (err != B_OK)
723 return err;
724 *key = rkey;
726 return B_OK;
730 void
731 set_modifier_key(uint32 modifier, uint32 key)
733 BMessage command(IS_SET_MODIFIER_KEY);
734 BMessage reply;
736 command.AddInt32("modifier", modifier);
737 command.AddInt32("key", key);
738 _control_input_server_(&command, &reply);
742 void
743 set_keyboard_locks(uint32 modifiers)
745 BMessage command(IS_SET_KEYBOARD_LOCKS);
746 BMessage reply;
748 command.AddInt32("locks", modifiers);
749 _control_input_server_(&command, &reply);
753 status_t
754 _restore_key_map_()
756 BMessage message(IS_RESTORE_KEY_MAP);
757 BMessage reply;
759 return _control_input_server_(&message, &reply);
763 rgb_color
764 keyboard_navigation_color()
766 // Queries the app_server
767 return ui_color(B_KEYBOARD_NAVIGATION_COLOR);
771 int32
772 count_workspaces()
774 uint32 columns;
775 uint32 rows;
776 BPrivate::get_workspaces_layout(&columns, &rows);
778 return columns * rows;
782 void
783 set_workspace_count(int32 count)
785 int32 squareRoot = (int32)sqrt(count);
787 int32 rows = 1;
788 for (int32 i = 2; i <= squareRoot; i++) {
789 if (count % i == 0)
790 rows = i;
793 int32 columns = count / rows;
795 BPrivate::set_workspaces_layout(columns, rows);
799 int32
800 current_workspace()
802 int32 index = 0;
804 BPrivate::AppServerLink link;
805 link.StartMessage(AS_CURRENT_WORKSPACE);
807 int32 status;
808 if (link.FlushWithReply(status) == B_OK && status == B_OK)
809 link.Read<int32>(&index);
811 return index;
815 void
816 activate_workspace(int32 workspace)
818 BPrivate::AppServerLink link;
819 link.StartMessage(AS_ACTIVATE_WORKSPACE);
820 link.Attach<int32>(workspace);
821 link.Attach<bool>(false);
822 link.Flush();
826 bigtime_t
827 idle_time()
829 bigtime_t idletime = 0;
831 BPrivate::AppServerLink link;
832 link.StartMessage(AS_IDLE_TIME);
834 int32 code;
835 if (link.FlushWithReply(code) == B_OK && code == B_OK)
836 link.Read<int64>(&idletime);
838 return idletime;
842 void
843 run_select_printer_panel()
845 if (be_roster == NULL)
846 return;
848 // Launches the Printer prefs app via the Roster
849 be_roster->Launch(PRNT_SIGNATURE_TYPE);
853 void
854 run_add_printer_panel()
856 // Launches the Printer prefs app via the Roster and asks it to
857 // add a printer
858 run_select_printer_panel();
860 BMessenger printerPanelMessenger(PRNT_SIGNATURE_TYPE);
861 printerPanelMessenger.SendMessage(PRINTERS_ADD_PRINTER);
865 void
866 run_be_about()
868 if (be_roster != NULL)
869 be_roster->Launch("application/x-vnd.Haiku-About");
873 void
874 set_focus_follows_mouse(bool follow)
876 // obviously deprecated API
877 set_mouse_mode(B_FOCUS_FOLLOWS_MOUSE);
881 bool
882 focus_follows_mouse()
884 return mouse_mode() == B_FOCUS_FOLLOWS_MOUSE;
888 void
889 set_mouse_mode(mode_mouse mode)
891 BPrivate::AppServerLink link;
892 link.StartMessage(AS_SET_MOUSE_MODE);
893 link.Attach<mode_mouse>(mode);
894 link.Flush();
898 mode_mouse
899 mouse_mode()
901 // Gets the mouse focus style, such as activate to click,
902 // focus to click, ...
903 mode_mouse mode = B_NORMAL_MOUSE;
905 BPrivate::AppServerLink link;
906 link.StartMessage(AS_GET_MOUSE_MODE);
908 int32 code;
909 if (link.FlushWithReply(code) == B_OK && code == B_OK)
910 link.Read<mode_mouse>(&mode);
912 return mode;
916 void
917 set_focus_follows_mouse_mode(mode_focus_follows_mouse mode)
919 BPrivate::AppServerLink link;
920 link.StartMessage(AS_SET_FOCUS_FOLLOWS_MOUSE_MODE);
921 link.Attach<mode_focus_follows_mouse>(mode);
922 link.Flush();
926 mode_focus_follows_mouse
927 focus_follows_mouse_mode()
929 mode_focus_follows_mouse mode = B_NORMAL_FOCUS_FOLLOWS_MOUSE;
931 BPrivate::AppServerLink link;
932 link.StartMessage(AS_GET_FOCUS_FOLLOWS_MOUSE_MODE);
934 int32 code;
935 if (link.FlushWithReply(code) == B_OK && code == B_OK)
936 link.Read<mode_focus_follows_mouse>(&mode);
938 return mode;
942 status_t
943 get_mouse(BPoint* screenWhere, uint32* buttons)
945 if (screenWhere == NULL && buttons == NULL)
946 return B_BAD_VALUE;
948 BPrivate::AppServerLink link;
949 link.StartMessage(AS_GET_CURSOR_POSITION);
951 int32 code;
952 status_t ret = link.FlushWithReply(code);
953 if (ret != B_OK)
954 return ret;
955 if (code != B_OK)
956 return code;
958 if (screenWhere != NULL)
959 ret = link.Read<BPoint>(screenWhere);
960 else {
961 BPoint dummy;
962 ret = link.Read<BPoint>(&dummy);
964 if (ret != B_OK)
965 return ret;
967 if (buttons != NULL)
968 ret = link.Read<uint32>(buttons);
969 else {
970 uint32 dummy;
971 ret = link.Read<uint32>(&dummy);
974 return ret;
978 status_t
979 get_mouse_bitmap(BBitmap** bitmap, BPoint* hotspot)
981 if (bitmap == NULL && hotspot == NULL)
982 return B_BAD_VALUE;
984 BPrivate::AppServerLink link;
985 link.StartMessage(AS_GET_CURSOR_BITMAP);
987 int32 code;
988 status_t status = link.FlushWithReply(code);
989 if (status != B_OK)
990 return status;
991 if (code != B_OK)
992 return code;
994 uint32 size = 0;
995 uint32 cursorWidth = 0;
996 uint32 cursorHeight = 0;
998 // if link.Read() returns an error, the same error will be returned on
999 // subsequent calls, so we'll check only the return value of the last call
1000 link.Read<uint32>(&size);
1001 link.Read<uint32>(&cursorWidth);
1002 link.Read<uint32>(&cursorHeight);
1003 if (hotspot == NULL) {
1004 BPoint dummy;
1005 link.Read<BPoint>(&dummy);
1006 } else
1007 link.Read<BPoint>(hotspot);
1009 void* data = NULL;
1010 if (size > 0)
1011 data = malloc(size);
1012 if (data == NULL)
1013 return B_NO_MEMORY;
1015 status = link.Read(data, size);
1016 if (status != B_OK) {
1017 free(data);
1018 return status;
1021 BBitmap* cursorBitmap = new (std::nothrow) BBitmap(BRect(0, 0,
1022 cursorWidth - 1, cursorHeight - 1), B_RGBA32);
1024 if (cursorBitmap == NULL) {
1025 free(data);
1026 return B_NO_MEMORY;
1028 status = cursorBitmap->InitCheck();
1029 if (status == B_OK)
1030 cursorBitmap->SetBits(data, size, 0, B_RGBA32);
1032 free(data);
1034 if (status == B_OK && bitmap != NULL)
1035 *bitmap = cursorBitmap;
1036 else
1037 delete cursorBitmap;
1039 return status;
1043 void
1044 set_accept_first_click(bool acceptFirstClick)
1046 BPrivate::AppServerLink link;
1047 link.StartMessage(AS_SET_ACCEPT_FIRST_CLICK);
1048 link.Attach<bool>(acceptFirstClick);
1049 link.Flush();
1053 bool
1054 accept_first_click()
1056 // Gets the accept first click status
1057 bool acceptFirstClick = false;
1059 BPrivate::AppServerLink link;
1060 link.StartMessage(AS_GET_ACCEPT_FIRST_CLICK);
1062 int32 code;
1063 if (link.FlushWithReply(code) == B_OK && code == B_OK)
1064 link.Read<bool>(&acceptFirstClick);
1066 return acceptFirstClick;
1070 rgb_color
1071 ui_color(color_which which)
1073 int32 index = color_which_to_index(which);
1074 if (index < 0 || index >= kColorWhichCount) {
1075 fprintf(stderr, "ui_color(): unknown color_which %d\n", which);
1076 return make_color(0, 0, 0);
1079 if (be_app != NULL) {
1080 server_read_only_memory* shared
1081 = BApplication::Private::ServerReadOnlyMemory();
1082 if (shared != NULL)
1083 return shared->colors[index];
1086 return kDefaultColors[index];
1090 void
1091 set_ui_color(const color_which &which, const rgb_color &color)
1093 int32 index = color_which_to_index(which);
1094 if (index < 0 || index >= kColorWhichCount) {
1095 fprintf(stderr, "set_ui_color(): unknown color_which %d\n", which);
1096 return;
1099 BPrivate::AppServerLink link;
1100 link.StartMessage(AS_SET_UI_COLOR);
1101 link.Attach<color_which>(which);
1102 link.Attach<rgb_color>(color);
1103 link.Flush();
1107 rgb_color
1108 tint_color(rgb_color color, float tint)
1110 rgb_color result;
1112 #define LIGHTEN(x) ((uint8)(255.0f - (255.0f - x) * tint))
1113 #define DARKEN(x) ((uint8)(x * (2 - tint)))
1115 if (tint < 1.0f) {
1116 result.red = LIGHTEN(color.red);
1117 result.green = LIGHTEN(color.green);
1118 result.blue = LIGHTEN(color.blue);
1119 result.alpha = color.alpha;
1120 } else {
1121 result.red = DARKEN(color.red);
1122 result.green = DARKEN(color.green);
1123 result.blue = DARKEN(color.blue);
1124 result.alpha = color.alpha;
1127 #undef LIGHTEN
1128 #undef DARKEN
1130 return result;
1134 rgb_color shift_color(rgb_color color, float shift);
1136 rgb_color
1137 shift_color(rgb_color color, float shift)
1139 return tint_color(color, shift);
1143 extern "C" status_t
1144 _init_interface_kit_()
1146 status_t status = BPrivate::PaletteConverter::InitializeDefault(true);
1147 if (status < B_OK)
1148 return status;
1150 // init global clipboard
1151 if (be_clipboard == NULL)
1152 be_clipboard = new BClipboard(NULL);
1154 // TODO: Could support different themes here in the future.
1155 be_control_look = new BControlLook();
1157 _init_global_fonts_();
1159 BPrivate::gWidthBuffer = new BPrivate::WidthBuffer;
1160 status = BPrivate::MenuPrivate::CreateBitmaps();
1161 if (status != B_OK)
1162 return status;
1164 _menu_info_ptr_ = &BMenu::sMenuInfo;
1166 status = get_menu_info(&BMenu::sMenuInfo);
1167 if (status != B_OK)
1168 return status;
1170 general_info.background_color = ui_color(B_PANEL_BACKGROUND_COLOR);
1171 general_info.mark_color = ui_color(B_CONTROL_MARK_COLOR);
1172 general_info.highlight_color = ui_color(B_CONTROL_HIGHLIGHT_COLOR);
1173 general_info.window_frame_color = ui_color(B_WINDOW_TAB_COLOR);
1174 general_info.color_frame = true;
1176 // TODO: fill the other static members
1178 return status;
1182 extern "C" status_t
1183 _fini_interface_kit_()
1185 BPrivate::MenuPrivate::DeleteBitmaps();
1187 delete BPrivate::gWidthBuffer;
1188 BPrivate::gWidthBuffer = NULL;
1190 delete be_control_look;
1191 be_control_look = NULL;
1193 // TODO: Anything else?
1195 return B_OK;
1200 namespace BPrivate {
1203 /*! \brief queries the server for the current decorator
1204 \param ref entry_ref into which to store current decorator's location
1205 \return boolean true/false
1207 bool
1208 get_decorator(BString& path)
1210 BPrivate::AppServerLink link;
1211 link.StartMessage(AS_GET_DECORATOR);
1213 int32 code;
1214 if (link.FlushWithReply(code) != B_OK || code != B_OK)
1215 return false;
1217 return link.ReadString(path) == B_OK;
1221 /*! \brief Private function which sets the window decorator for the system.
1222 \param entry_ref to the decorator to set
1224 Will return detailed error status via status_t
1226 status_t
1227 set_decorator(const BString& path)
1229 BPrivate::AppServerLink link;
1231 link.StartMessage(AS_SET_DECORATOR);
1233 link.AttachString(path.String());
1234 link.Flush();
1236 status_t error = B_OK;
1237 link.Read<status_t>(&error);
1239 return error;
1243 /*! \brief sets a window to preview a given decorator
1244 \param path path to any given decorator add-on
1245 \param window pointer to BWindow which will show decorator
1247 Piggy-backs on BWindow::SetDecoratorSettings(...)
1249 status_t
1250 preview_decorator(const BString& path, BWindow* window)
1252 if (window == NULL)
1253 return B_ERROR;
1255 BMessage msg('prVu');
1256 msg.AddString("preview", path.String());
1258 return window->SetDecoratorSettings(msg);
1262 status_t
1263 get_application_order(int32 workspace, team_id** _applications,
1264 int32* _count)
1266 BPrivate::AppServerLink link;
1268 link.StartMessage(AS_GET_APPLICATION_ORDER);
1269 link.Attach<int32>(workspace);
1271 int32 code;
1272 status_t status = link.FlushWithReply(code);
1273 if (status != B_OK)
1274 return status;
1275 if (code != B_OK)
1276 return code;
1278 int32 count;
1279 link.Read<int32>(&count);
1281 *_applications = (team_id*)malloc(count * sizeof(team_id));
1282 if (*_applications == NULL)
1283 return B_NO_MEMORY;
1285 link.Read(*_applications, count * sizeof(team_id));
1286 *_count = count;
1287 return B_OK;
1291 status_t
1292 get_window_order(int32 workspace, int32** _tokens, int32* _count)
1294 BPrivate::AppServerLink link;
1296 link.StartMessage(AS_GET_WINDOW_ORDER);
1297 link.Attach<int32>(workspace);
1299 int32 code;
1300 status_t status = link.FlushWithReply(code);
1301 if (status != B_OK)
1302 return status;
1303 if (code != B_OK)
1304 return code;
1306 int32 count;
1307 link.Read<int32>(&count);
1309 *_tokens = (int32*)malloc(count * sizeof(int32));
1310 if (*_tokens == NULL)
1311 return B_NO_MEMORY;
1313 link.Read(*_tokens, count * sizeof(int32));
1314 *_count = count;
1315 return B_OK;
1319 } // namespace BPrivate
1321 // These methods were marked with "Danger, will Robinson!" in
1322 // the OpenTracker source, so we might not want to be compatible
1323 // here.
1324 // In any way, we would need to update Deskbar to use our
1325 // replacements, so we could as well just implement them...
1327 void
1328 do_window_action(int32 windowToken, int32 action, BRect zoomRect, bool zoom)
1330 BPrivate::AppServerLink link;
1332 link.StartMessage(AS_WINDOW_ACTION);
1333 link.Attach<int32>(windowToken);
1334 link.Attach<int32>(action);
1335 // we don't have any zooming effect
1337 link.Flush();
1341 client_window_info*
1342 get_window_info(int32 serverToken)
1344 BPrivate::AppServerLink link;
1346 link.StartMessage(AS_GET_WINDOW_INFO);
1347 link.Attach<int32>(serverToken);
1349 int32 code;
1350 if (link.FlushWithReply(code) != B_OK || code != B_OK)
1351 return NULL;
1353 int32 size;
1354 link.Read<int32>(&size);
1356 client_window_info* info = (client_window_info*)malloc(size);
1357 if (info == NULL)
1358 return NULL;
1360 link.Read(info, size);
1361 return info;
1365 int32*
1366 get_token_list(team_id team, int32* _count)
1368 BPrivate::AppServerLink link;
1370 link.StartMessage(AS_GET_WINDOW_LIST);
1371 link.Attach<team_id>(team);
1373 int32 code;
1374 if (link.FlushWithReply(code) != B_OK || code != B_OK)
1375 return NULL;
1377 int32 count;
1378 link.Read<int32>(&count);
1380 int32* tokens = (int32*)malloc(count * sizeof(int32));
1381 if (tokens == NULL)
1382 return NULL;
1384 link.Read(tokens, count * sizeof(int32));
1385 *_count = count;
1386 return tokens;
1390 void
1391 do_bring_to_front_team(BRect zoomRect, team_id team, bool zoom)
1393 BPrivate::AppServerLink link;
1395 link.StartMessage(AS_BRING_TEAM_TO_FRONT);
1396 link.Attach<team_id>(team);
1397 // we don't have any zooming effect
1399 link.Flush();
1403 void
1404 do_minimize_team(BRect zoomRect, team_id team, bool zoom)
1406 BPrivate::AppServerLink link;
1408 link.StartMessage(AS_MINIMIZE_TEAM);
1409 link.Attach<team_id>(team);
1410 // we don't have any zooming effect
1412 link.Flush();
1416 // #pragma mark - truncate string
1419 void
1420 truncate_string(BString& string, uint32 mode, float width,
1421 const float* escapementArray, float fontSize, float ellipsisWidth,
1422 int32 charCount)
1424 // add a tiny amount to the width to make floating point inaccuracy
1425 // not drop chars that would actually fit exactly
1426 width += 1.f / 128;
1428 switch (mode) {
1429 case B_TRUNCATE_BEGINNING:
1431 float totalWidth = 0;
1432 for (int32 i = charCount - 1; i >= 0; i--) {
1433 float charWidth = escapementArray[i] * fontSize;
1434 if (totalWidth + charWidth > width) {
1435 // we need to truncate
1436 while (totalWidth + ellipsisWidth > width) {
1437 // remove chars until there's enough space for the
1438 // ellipsis
1439 if (++i == charCount) {
1440 // we've reached the end of the string and still
1441 // no space, so return an empty string
1442 string.Truncate(0);
1443 return;
1446 totalWidth -= escapementArray[i] * fontSize;
1449 string.RemoveChars(0, i + 1);
1450 string.PrependChars(B_UTF8_ELLIPSIS, 1);
1451 return;
1454 totalWidth += charWidth;
1457 break;
1460 case B_TRUNCATE_END:
1462 float totalWidth = 0;
1463 for (int32 i = 0; i < charCount; i++) {
1464 float charWidth = escapementArray[i] * fontSize;
1465 if (totalWidth + charWidth > width) {
1466 // we need to truncate
1467 while (totalWidth + ellipsisWidth > width) {
1468 // remove chars until there's enough space for the
1469 // ellipsis
1470 if (i-- == 0) {
1471 // we've reached the start of the string and still
1472 // no space, so return an empty string
1473 string.Truncate(0);
1474 return;
1477 totalWidth -= escapementArray[i] * fontSize;
1480 string.RemoveChars(i, charCount - i);
1481 string.AppendChars(B_UTF8_ELLIPSIS, 1);
1482 return;
1485 totalWidth += charWidth;
1488 break;
1491 case B_TRUNCATE_MIDDLE:
1492 case B_TRUNCATE_SMART:
1494 float leftWidth = 0;
1495 float rightWidth = 0;
1496 int32 leftIndex = 0;
1497 int32 rightIndex = charCount - 1;
1498 bool left = true;
1500 for (int32 i = 0; i < charCount; i++) {
1501 float charWidth
1502 = escapementArray[left ? leftIndex : rightIndex] * fontSize;
1504 if (leftWidth + rightWidth + charWidth > width) {
1505 // we need to truncate
1506 while (leftWidth + rightWidth + ellipsisWidth > width) {
1507 // remove chars until there's enough space for the
1508 // ellipsis
1509 if (leftIndex == 0 && rightIndex == charCount - 1) {
1510 // we've reached both ends of the string and still
1511 // no space, so return an empty string
1512 string.Truncate(0);
1513 return;
1516 if (leftIndex > 0 && (rightIndex == charCount - 1
1517 || leftWidth > rightWidth)) {
1518 // remove char on the left
1519 leftWidth -= escapementArray[--leftIndex]
1520 * fontSize;
1521 } else {
1522 // remove char on the right
1523 rightWidth -= escapementArray[++rightIndex]
1524 * fontSize;
1528 string.RemoveChars(leftIndex, rightIndex + 1 - leftIndex);
1529 string.InsertChars(B_UTF8_ELLIPSIS, 1, leftIndex);
1530 return;
1533 if (left) {
1534 leftIndex++;
1535 leftWidth += charWidth;
1536 } else {
1537 rightIndex--;
1538 rightWidth += charWidth;
1541 left = rightWidth > leftWidth;
1544 break;
1548 // we've run through without the need to truncate, leave the string as it is