2 * Copyright 2001-2015, Haiku, Inc.
3 * Distributed under the terms of the MIT License.
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>
11 * Joseph Groover <looncraz@looncraz.net>
15 /*! Global functions and variables for the Interface Kit */
18 #include <InterfaceDefs.h>
26 #include <Clipboard.h>
27 #include <ControlLook.h>
33 #include <ScrollBar.h>
38 #include <ApplicationPrivate.h>
39 #include <AppServerLink.h>
40 #include <ColorConversion.h>
41 #include <DecorInfo.h>
42 #include <DefaultColors.h>
43 #include <DesktopLink.h>
44 #include <HaikuControlLook.h>
45 #include <InputServerTypes.h>
46 #include <input_globals.h>
47 #include <InterfacePrivate.h>
48 #include <MenuPrivate.h>
49 #include <pr_server.h>
50 #include <ServerProtocol.h>
51 #include <ServerReadOnlyMemory.h>
52 #include <truncate_string.h>
53 #include <utf8_functions.h>
54 #include <WidthBuffer.h>
55 #include <WindowInfo.h>
58 using namespace BPrivate
;
60 // some other weird struct exported by BeOS, it's not initialized, though
61 struct general_ui_info
{
62 rgb_color background_color
;
64 rgb_color highlight_color
;
66 rgb_color window_frame_color
;
69 struct general_ui_info general_info
;
71 menu_info
*_menu_info_ptr_
;
73 extern "C" const char B_NOTIFICATION_SENDER
[] = "be:sender";
75 static const rgb_color _kDefaultColors
[kColorWhichCount
] = {
76 {216, 216, 216, 255}, // B_PANEL_BACKGROUND_COLOR
77 {216, 216, 216, 255}, // B_MENU_BACKGROUND_COLOR
78 {255, 203, 0, 255}, // B_WINDOW_TAB_COLOR
79 {0, 0, 229, 255}, // B_KEYBOARD_NAVIGATION_COLOR
80 {51, 102, 152, 255}, // B_DESKTOP_COLOR
81 {153, 153, 153, 255}, // B_MENU_SELECTED_BACKGROUND_COLOR
82 {0, 0, 0, 255}, // B_MENU_ITEM_TEXT_COLOR
83 {0, 0, 0, 255}, // B_MENU_SELECTED_ITEM_TEXT_COLOR
84 {0, 0, 0, 255}, // B_MENU_SELECTED_BORDER_COLOR
85 {0, 0, 0, 255}, // B_PANEL_TEXT_COLOR
86 {255, 255, 255, 255}, // B_DOCUMENT_BACKGROUND_COLOR
87 {0, 0, 0, 255}, // B_DOCUMENT_TEXT_COLOR
88 {245, 245, 245, 255}, // B_CONTROL_BACKGROUND_COLOR
89 {0, 0, 0, 255}, // B_CONTROL_TEXT_COLOR
90 {172, 172, 172, 255}, // B_CONTROL_BORDER_COLOR
91 {102, 152, 203, 255}, // B_CONTROL_HIGHLIGHT_COLOR
92 {0, 0, 0, 255}, // B_NAVIGATION_PULSE_COLOR
93 {255, 255, 255, 255}, // B_SHINE_COLOR
94 {0, 0, 0, 255}, // B_SHADOW_COLOR
95 {255, 255, 216, 255}, // B_TOOLTIP_BACKGROUND_COLOR
96 {0, 0, 0, 255}, // B_TOOLTIP_TEXT_COLOR
97 {0, 0, 0, 255}, // B_WINDOW_TEXT_COLOR
98 {232, 232, 232, 255}, // B_WINDOW_INACTIVE_TAB_COLOR
99 {80, 80, 80, 255}, // B_WINDOW_INACTIVE_TEXT_COLOR
100 {224, 224, 224, 255}, // B_WINDOW_BORDER_COLOR
101 {232, 232, 232, 255}, // B_WINDOW_INACTIVE_BORDER_COLOR
102 {27, 82, 140, 255}, // B_CONTROL_MARK_COLOR
103 {255, 255, 255, 255}, // B_LIST_BACKGROUND_COLOR
104 {190, 190, 190, 255}, // B_LIST_SELECTED_BACKGROUND_COLOR
105 {0, 0, 0, 255}, // B_LIST_ITEM_TEXT_COLOR
106 {0, 0, 0, 255}, // B_LIST_SELECTED_ITEM_TEXT_COLOR
107 {216, 216, 216, 255}, // B_SCROLL_BAR_THUMB_COLOR
108 {51, 102, 187, 255}, // B_LINK_TEXT_COLOR
109 {102, 152, 203, 255}, // B_LINK_HOVER_COLOR
110 {145, 112, 155, 255}, // B_LINK_VISITED_COLOR
111 {121, 142, 203, 255}, // B_LINK_ACTIVE_COLOR
112 {50, 150, 255, 255}, // B_STATUS_BAR_COLOR
114 {46, 204, 64, 255}, // B_SUCCESS_COLOR
115 {255, 65, 54, 255}, // B_FAILURE_COLOR
118 const rgb_color
* BPrivate::kDefaultColors
= &_kDefaultColors
[0];
121 static const char* kColorNames
[kColorWhichCount
] = {
122 "B_PANEL_BACKGROUND_COLOR",
123 "B_MENU_BACKGROUND_COLOR",
124 "B_WINDOW_TAB_COLOR",
125 "B_KEYBOARD_NAVIGATION_COLOR",
127 "B_MENU_SELECTED_BACKGROUND_COLOR",
128 "B_MENU_ITEM_TEXT_COLOR",
129 "B_MENU_SELECTED_ITEM_TEXT_COLOR",
130 "B_MENU_SELECTED_BORDER_COLOR",
131 "B_PANEL_TEXT_COLOR",
132 "B_DOCUMENT_BACKGROUND_COLOR",
133 "B_DOCUMENT_TEXT_COLOR",
134 "B_CONTROL_BACKGROUND_COLOR",
135 "B_CONTROL_TEXT_COLOR",
136 "B_CONTROL_BORDER_COLOR",
137 "B_CONTROL_HIGHLIGHT_COLOR",
138 "B_NAVIGATION_PULSE_COLOR",
141 "B_TOOLTIP_BACKGROUND_COLOR",
142 "B_TOOLTIP_TEXT_COLOR",
143 "B_WINDOW_TEXT_COLOR",
144 "B_WINDOW_INACTIVE_TAB_COLOR",
145 "B_WINDOW_INACTIVE_TEXT_COLOR",
146 "B_WINDOW_BORDER_COLOR",
147 "B_WINDOW_INACTIVE_BORDER_COLOR",
148 "B_CONTROL_MARK_COLOR",
149 "B_LIST_BACKGROUND_COLOR",
150 "B_LIST_SELECTED_BACKGROUND_COLOR",
151 "B_LIST_ITEM_TEXT_COLOR",
152 "B_LIST_SELECTED_ITEM_TEXT_COLOR",
153 "B_SCROLL_BAR_THUMB_COLOR",
155 "B_LINK_HOVER_COLOR",
156 "B_LINK_VISITED_COLOR",
157 "B_LINK_ACTIVE_COLOR",
158 "B_STATUS_BAR_COLOR",
169 /*! Fills the \a width, \a height, and \a colorSpace parameters according
170 to the window screen's mode.
171 Returns \c true if the mode is known.
174 get_mode_parameter(uint32 mode
, int32
& width
, int32
& height
,
178 case B_8_BIT_640x480
:
179 case B_8_BIT_800x600
:
180 case B_8_BIT_1024x768
:
181 case B_8_BIT_1152x900
:
182 case B_8_BIT_1280x1024
:
183 case B_8_BIT_1600x1200
:
184 colorSpace
= B_CMAP8
;
187 case B_15_BIT_640x480
:
188 case B_15_BIT_800x600
:
189 case B_15_BIT_1024x768
:
190 case B_15_BIT_1152x900
:
191 case B_15_BIT_1280x1024
:
192 case B_15_BIT_1600x1200
:
193 colorSpace
= B_RGB15
;
196 case B_16_BIT_640x480
:
197 case B_16_BIT_800x600
:
198 case B_16_BIT_1024x768
:
199 case B_16_BIT_1152x900
:
200 case B_16_BIT_1280x1024
:
201 case B_16_BIT_1600x1200
:
202 colorSpace
= B_RGB16
;
205 case B_32_BIT_640x480
:
206 case B_32_BIT_800x600
:
207 case B_32_BIT_1024x768
:
208 case B_32_BIT_1152x900
:
209 case B_32_BIT_1280x1024
:
210 case B_32_BIT_1600x1200
:
211 colorSpace
= B_RGB32
;
219 case B_8_BIT_640x480
:
220 case B_15_BIT_640x480
:
221 case B_16_BIT_640x480
:
222 case B_32_BIT_640x480
:
223 width
= 640; height
= 480;
226 case B_8_BIT_800x600
:
227 case B_15_BIT_800x600
:
228 case B_16_BIT_800x600
:
229 case B_32_BIT_800x600
:
230 width
= 800; height
= 600;
233 case B_8_BIT_1024x768
:
234 case B_15_BIT_1024x768
:
235 case B_16_BIT_1024x768
:
236 case B_32_BIT_1024x768
:
237 width
= 1024; height
= 768;
240 case B_8_BIT_1152x900
:
241 case B_15_BIT_1152x900
:
242 case B_16_BIT_1152x900
:
243 case B_32_BIT_1152x900
:
244 width
= 1152; height
= 900;
247 case B_8_BIT_1280x1024
:
248 case B_15_BIT_1280x1024
:
249 case B_16_BIT_1280x1024
:
250 case B_32_BIT_1280x1024
:
251 width
= 1280; height
= 1024;
254 case B_8_BIT_1600x1200
:
255 case B_15_BIT_1600x1200
:
256 case B_16_BIT_1600x1200
:
257 case B_32_BIT_1600x1200
:
258 width
= 1600; height
= 1200;
267 get_workspaces_layout(uint32
* _columns
, uint32
* _rows
)
272 BPrivate::AppServerLink link
;
273 link
.StartMessage(AS_GET_WORKSPACE_LAYOUT
);
276 if (link
.FlushWithReply(status
) == B_OK
&& status
== B_OK
) {
277 link
.Read
<int32
>(&columns
);
278 link
.Read
<int32
>(&rows
);
281 if (_columns
!= NULL
)
289 set_workspaces_layout(uint32 columns
, uint32 rows
)
291 if (columns
< 1 || rows
< 1)
294 BPrivate::AppServerLink link
;
295 link
.StartMessage(AS_SET_WORKSPACE_LAYOUT
);
296 link
.Attach
<int32
>(columns
);
297 link
.Attach
<int32
>(rows
);
302 } // namespace BPrivate
306 set_subpixel_antialiasing(bool subpix
)
308 BPrivate::AppServerLink link
;
310 link
.StartMessage(AS_SET_SUBPIXEL_ANTIALIASING
);
311 link
.Attach
<bool>(subpix
);
317 get_subpixel_antialiasing(bool* subpix
)
319 BPrivate::AppServerLink link
;
321 link
.StartMessage(AS_GET_SUBPIXEL_ANTIALIASING
);
322 int32 status
= B_ERROR
;
323 if (link
.FlushWithReply(status
) != B_OK
|| status
< B_OK
)
325 link
.Read
<bool>(subpix
);
331 set_hinting_mode(uint8 hinting
)
333 BPrivate::AppServerLink link
;
335 link
.StartMessage(AS_SET_HINTING
);
336 link
.Attach
<uint8
>(hinting
);
342 get_hinting_mode(uint8
* hinting
)
344 BPrivate::AppServerLink link
;
346 link
.StartMessage(AS_GET_HINTING
);
347 int32 status
= B_ERROR
;
348 if (link
.FlushWithReply(status
) != B_OK
|| status
< B_OK
)
350 link
.Read
<uint8
>(hinting
);
356 set_average_weight(uint8 averageWeight
)
358 BPrivate::AppServerLink link
;
360 link
.StartMessage(AS_SET_SUBPIXEL_AVERAGE_WEIGHT
);
361 link
.Attach
<uint8
>(averageWeight
);
367 get_average_weight(uint8
* averageWeight
)
369 BPrivate::AppServerLink link
;
371 link
.StartMessage(AS_GET_SUBPIXEL_AVERAGE_WEIGHT
);
372 int32 status
= B_ERROR
;
373 if (link
.FlushWithReply(status
) != B_OK
|| status
< B_OK
)
375 link
.Read
<uint8
>(averageWeight
);
381 set_is_subpixel_ordering_regular(bool subpixelOrdering
)
383 BPrivate::AppServerLink link
;
385 link
.StartMessage(AS_SET_SUBPIXEL_ORDERING
);
386 link
.Attach
<bool>(subpixelOrdering
);
392 get_is_subpixel_ordering_regular(bool* subpixelOrdering
)
394 BPrivate::AppServerLink link
;
396 link
.StartMessage(AS_GET_SUBPIXEL_ORDERING
);
397 int32 status
= B_ERROR
;
398 if (link
.FlushWithReply(status
) != B_OK
|| status
< B_OK
)
400 link
.Read
<bool>(subpixelOrdering
);
408 return BScreen(B_MAIN_SCREEN_ID
).ColorMap();
413 set_screen_space(int32 index
, uint32 space
, bool stick
)
418 if (!BPrivate::get_mode_parameter(space
, width
, height
, depth
))
421 BScreen
screen(B_MAIN_SCREEN_ID
);
424 // TODO: What about refresh rate ?
425 // currently we get it from the current video mode, but
426 // this might be not so wise.
427 status_t status
= screen
.GetMode(index
, &mode
);
431 mode
.virtual_width
= width
;
432 mode
.virtual_height
= height
;
435 return screen
.SetMode(index
, &mode
, stick
);
440 get_scroll_bar_info(scroll_bar_info
*info
)
445 BPrivate::AppServerLink link
;
446 link
.StartMessage(AS_GET_SCROLLBAR_INFO
);
449 if (link
.FlushWithReply(code
) == B_OK
451 link
.Read
<scroll_bar_info
>(info
);
460 set_scroll_bar_info(scroll_bar_info
*info
)
465 BPrivate::AppServerLink link
;
468 link
.StartMessage(AS_SET_SCROLLBAR_INFO
);
469 link
.Attach
<scroll_bar_info
>(*info
);
471 if (link
.FlushWithReply(code
) == B_OK
480 get_mouse_type(int32
*type
)
482 BMessage
command(IS_GET_MOUSE_TYPE
);
485 status_t err
= _control_input_server_(&command
, &reply
);
488 return reply
.FindInt32("mouse_type", type
);
493 set_mouse_type(int32 type
)
495 BMessage
command(IS_SET_MOUSE_TYPE
);
498 status_t err
= command
.AddInt32("mouse_type", type
);
501 return _control_input_server_(&command
, &reply
);
506 get_mouse_map(mouse_map
*map
)
508 BMessage
command(IS_GET_MOUSE_MAP
);
510 const void *data
= 0;
513 status_t err
= _control_input_server_(&command
, &reply
);
515 err
= reply
.FindData("mousemap", B_RAW_TYPE
, &data
, &count
);
519 memcpy(map
, data
, count
);
526 set_mouse_map(mouse_map
*map
)
528 BMessage
command(IS_SET_MOUSE_MAP
);
531 status_t err
= command
.AddData("mousemap", B_RAW_TYPE
, map
,
535 return _control_input_server_(&command
, &reply
);
540 get_click_speed(bigtime_t
*speed
)
542 BMessage
command(IS_GET_CLICK_SPEED
);
545 status_t err
= _control_input_server_(&command
, &reply
);
549 if (reply
.FindInt64("speed", speed
) != B_OK
)
557 set_click_speed(bigtime_t speed
)
559 BMessage
command(IS_SET_CLICK_SPEED
);
561 command
.AddInt64("speed", speed
);
562 return _control_input_server_(&command
, &reply
);
567 get_mouse_speed(int32
*speed
)
569 BMessage
command(IS_GET_MOUSE_SPEED
);
572 status_t err
= _control_input_server_(&command
, &reply
);
576 if (reply
.FindInt32("speed", speed
) != B_OK
)
584 set_mouse_speed(int32 speed
)
586 BMessage
command(IS_SET_MOUSE_SPEED
);
588 command
.AddInt32("speed", speed
);
589 return _control_input_server_(&command
, &reply
);
594 get_mouse_acceleration(int32
*speed
)
596 BMessage
command(IS_GET_MOUSE_ACCELERATION
);
599 _control_input_server_(&command
, &reply
);
601 if (reply
.FindInt32("speed", speed
) != B_OK
)
609 set_mouse_acceleration(int32 speed
)
611 BMessage
command(IS_SET_MOUSE_ACCELERATION
);
613 command
.AddInt32("speed", speed
);
614 return _control_input_server_(&command
, &reply
);
619 get_key_repeat_rate(int32
*rate
)
621 BMessage
command(IS_GET_KEY_REPEAT_RATE
);
624 _control_input_server_(&command
, &reply
);
626 if (reply
.FindInt32("rate", rate
) != B_OK
)
634 set_key_repeat_rate(int32 rate
)
636 BMessage
command(IS_SET_KEY_REPEAT_RATE
);
638 command
.AddInt32("rate", rate
);
639 return _control_input_server_(&command
, &reply
);
644 get_key_repeat_delay(bigtime_t
*delay
)
646 BMessage
command(IS_GET_KEY_REPEAT_DELAY
);
649 _control_input_server_(&command
, &reply
);
651 if (reply
.FindInt64("delay", delay
) != B_OK
)
659 set_key_repeat_delay(bigtime_t delay
)
661 BMessage
command(IS_SET_KEY_REPEAT_DELAY
);
663 command
.AddInt64("delay", delay
);
664 return _control_input_server_(&command
, &reply
);
671 BMessage
command(IS_GET_MODIFIERS
);
675 _control_input_server_(&command
, &reply
);
677 if (reply
.FindInt32("status", &err
) != B_OK
)
680 if (reply
.FindInt32("modifiers", &modifier
) != B_OK
)
688 get_key_info(key_info
*info
)
690 BMessage
command(IS_GET_KEY_INFO
);
692 const void *data
= 0;
696 _control_input_server_(&command
, &reply
);
698 if (reply
.FindInt32("status", &err
) != B_OK
)
701 if (reply
.FindData("key_info", B_ANY_TYPE
, &data
, &count
) != B_OK
)
704 memcpy(info
, data
, count
);
710 get_key_map(key_map
**map
, char **key_buffer
)
712 _get_key_map(map
, key_buffer
, NULL
);
717 _get_key_map(key_map
**map
, char **key_buffer
, ssize_t
*key_buffer_size
)
719 BMessage
command(IS_GET_KEY_MAP
);
721 ssize_t map_count
, key_count
;
722 const void *map_array
= 0, *key_array
= 0;
723 if (key_buffer_size
== NULL
)
724 key_buffer_size
= &key_count
;
726 _control_input_server_(&command
, &reply
);
728 if (reply
.FindData("keymap", B_ANY_TYPE
, &map_array
, &map_count
) != B_OK
) {
729 *map
= 0; *key_buffer
= 0;
733 if (reply
.FindData("key_buffer", B_ANY_TYPE
, &key_array
, key_buffer_size
)
735 *map
= 0; *key_buffer
= 0;
739 *map
= (key_map
*)malloc(map_count
);
740 memcpy(*map
, map_array
, map_count
);
741 *key_buffer
= (char *)malloc(*key_buffer_size
);
742 memcpy(*key_buffer
, key_array
, *key_buffer_size
);
747 get_keyboard_id(uint16
*id
)
749 BMessage
command(IS_GET_KEYBOARD_ID
);
753 _control_input_server_(&command
, &reply
);
755 status_t err
= reply
.FindInt16("id", (int16
*)&kid
);
765 get_modifier_key(uint32 modifier
, uint32
*key
)
767 BMessage
command(IS_GET_MODIFIER_KEY
);
771 command
.AddInt32("modifier", modifier
);
772 _control_input_server_(&command
, &reply
);
774 status_t err
= reply
.FindInt32("key", (int32
*) &rkey
);
784 set_modifier_key(uint32 modifier
, uint32 key
)
786 BMessage
command(IS_SET_MODIFIER_KEY
);
789 command
.AddInt32("modifier", modifier
);
790 command
.AddInt32("key", key
);
791 _control_input_server_(&command
, &reply
);
796 set_keyboard_locks(uint32 modifiers
)
798 BMessage
command(IS_SET_KEYBOARD_LOCKS
);
801 command
.AddInt32("locks", modifiers
);
802 _control_input_server_(&command
, &reply
);
809 BMessage
message(IS_RESTORE_KEY_MAP
);
812 return _control_input_server_(&message
, &reply
);
817 keyboard_navigation_color()
819 // Queries the app_server
820 return ui_color(B_KEYBOARD_NAVIGATION_COLOR
);
829 BPrivate::get_workspaces_layout(&columns
, &rows
);
831 return columns
* rows
;
836 set_workspace_count(int32 count
)
838 int32 squareRoot
= (int32
)sqrt(count
);
841 for (int32 i
= 2; i
<= squareRoot
; i
++) {
846 int32 columns
= count
/ rows
;
848 BPrivate::set_workspaces_layout(columns
, rows
);
857 BPrivate::AppServerLink link
;
858 link
.StartMessage(AS_CURRENT_WORKSPACE
);
861 if (link
.FlushWithReply(status
) == B_OK
&& status
== B_OK
)
862 link
.Read
<int32
>(&index
);
869 activate_workspace(int32 workspace
)
871 BPrivate::AppServerLink link
;
872 link
.StartMessage(AS_ACTIVATE_WORKSPACE
);
873 link
.Attach
<int32
>(workspace
);
874 link
.Attach
<bool>(false);
882 bigtime_t idletime
= 0;
884 BPrivate::AppServerLink link
;
885 link
.StartMessage(AS_IDLE_TIME
);
888 if (link
.FlushWithReply(code
) == B_OK
&& code
== B_OK
)
889 link
.Read
<int64
>(&idletime
);
896 run_select_printer_panel()
898 if (be_roster
== NULL
)
901 // Launches the Printer prefs app via the Roster
902 be_roster
->Launch(PRNT_SIGNATURE_TYPE
);
907 run_add_printer_panel()
909 // Launches the Printer prefs app via the Roster and asks it to
911 run_select_printer_panel();
913 BMessenger
printerPanelMessenger(PRNT_SIGNATURE_TYPE
);
914 printerPanelMessenger
.SendMessage(PRINTERS_ADD_PRINTER
);
921 if (be_roster
!= NULL
)
922 be_roster
->Launch("application/x-vnd.Haiku-About");
927 set_focus_follows_mouse(bool follow
)
929 // obviously deprecated API
930 set_mouse_mode(B_FOCUS_FOLLOWS_MOUSE
);
935 focus_follows_mouse()
937 return mouse_mode() == B_FOCUS_FOLLOWS_MOUSE
;
942 set_mouse_mode(mode_mouse mode
)
944 BPrivate::AppServerLink link
;
945 link
.StartMessage(AS_SET_MOUSE_MODE
);
946 link
.Attach
<mode_mouse
>(mode
);
954 // Gets the mouse focus style, such as activate to click,
955 // focus to click, ...
956 mode_mouse mode
= B_NORMAL_MOUSE
;
958 BPrivate::AppServerLink link
;
959 link
.StartMessage(AS_GET_MOUSE_MODE
);
962 if (link
.FlushWithReply(code
) == B_OK
&& code
== B_OK
)
963 link
.Read
<mode_mouse
>(&mode
);
970 set_focus_follows_mouse_mode(mode_focus_follows_mouse mode
)
972 BPrivate::AppServerLink link
;
973 link
.StartMessage(AS_SET_FOCUS_FOLLOWS_MOUSE_MODE
);
974 link
.Attach
<mode_focus_follows_mouse
>(mode
);
979 mode_focus_follows_mouse
980 focus_follows_mouse_mode()
982 mode_focus_follows_mouse mode
= B_NORMAL_FOCUS_FOLLOWS_MOUSE
;
984 BPrivate::AppServerLink link
;
985 link
.StartMessage(AS_GET_FOCUS_FOLLOWS_MOUSE_MODE
);
988 if (link
.FlushWithReply(code
) == B_OK
&& code
== B_OK
)
989 link
.Read
<mode_focus_follows_mouse
>(&mode
);
996 get_mouse(BPoint
* screenWhere
, uint32
* buttons
)
998 if (screenWhere
== NULL
&& buttons
== NULL
)
1001 BPrivate::AppServerLink link
;
1002 link
.StartMessage(AS_GET_CURSOR_POSITION
);
1005 status_t ret
= link
.FlushWithReply(code
);
1011 if (screenWhere
!= NULL
)
1012 ret
= link
.Read
<BPoint
>(screenWhere
);
1015 ret
= link
.Read
<BPoint
>(&dummy
);
1020 if (buttons
!= NULL
)
1021 ret
= link
.Read
<uint32
>(buttons
);
1024 ret
= link
.Read
<uint32
>(&dummy
);
1032 get_mouse_bitmap(BBitmap
** bitmap
, BPoint
* hotspot
)
1034 if (bitmap
== NULL
&& hotspot
== NULL
)
1037 BPrivate::AppServerLink link
;
1038 link
.StartMessage(AS_GET_CURSOR_BITMAP
);
1041 status_t status
= link
.FlushWithReply(code
);
1048 uint32 cursorWidth
= 0;
1049 uint32 cursorHeight
= 0;
1051 // if link.Read() returns an error, the same error will be returned on
1052 // subsequent calls, so we'll check only the return value of the last call
1053 link
.Read
<uint32
>(&size
);
1054 link
.Read
<uint32
>(&cursorWidth
);
1055 link
.Read
<uint32
>(&cursorHeight
);
1056 if (hotspot
== NULL
) {
1058 link
.Read
<BPoint
>(&dummy
);
1060 link
.Read
<BPoint
>(hotspot
);
1064 data
= malloc(size
);
1068 status
= link
.Read(data
, size
);
1069 if (status
!= B_OK
) {
1074 BBitmap
* cursorBitmap
= new (std::nothrow
) BBitmap(BRect(0, 0,
1075 cursorWidth
- 1, cursorHeight
- 1), B_RGBA32
);
1077 if (cursorBitmap
== NULL
) {
1081 status
= cursorBitmap
->InitCheck();
1083 cursorBitmap
->SetBits(data
, size
, 0, B_RGBA32
);
1087 if (status
== B_OK
&& bitmap
!= NULL
)
1088 *bitmap
= cursorBitmap
;
1090 delete cursorBitmap
;
1097 set_accept_first_click(bool acceptFirstClick
)
1099 BPrivate::AppServerLink link
;
1100 link
.StartMessage(AS_SET_ACCEPT_FIRST_CLICK
);
1101 link
.Attach
<bool>(acceptFirstClick
);
1107 accept_first_click()
1109 // Gets the accept first click status
1110 bool acceptFirstClick
= false;
1112 BPrivate::AppServerLink link
;
1113 link
.StartMessage(AS_GET_ACCEPT_FIRST_CLICK
);
1116 if (link
.FlushWithReply(code
) == B_OK
&& code
== B_OK
)
1117 link
.Read
<bool>(&acceptFirstClick
);
1119 return acceptFirstClick
;
1124 ui_color(color_which which
)
1126 int32 index
= color_which_to_index(which
);
1127 if (index
< 0 || index
>= kColorWhichCount
) {
1128 fprintf(stderr
, "ui_color(): unknown color_which %d\n", which
);
1129 return make_color(0, 0, 0);
1132 if (be_app
!= NULL
) {
1133 server_read_only_memory
* shared
1134 = BApplication::Private::ServerReadOnlyMemory();
1135 if (shared
!= NULL
) {
1136 // check for unset colors
1137 if (shared
->colors
[index
] == B_TRANSPARENT_COLOR
)
1138 shared
->colors
[index
] = kDefaultColors
[index
];
1140 return shared
->colors
[index
];
1144 return kDefaultColors
[index
];
1149 ui_color_name(color_which which
)
1151 // Suppress warnings for B_NO_COLOR.
1152 if (which
== B_NO_COLOR
)
1155 int32 index
= color_which_to_index(which
);
1156 if (index
< 0 || index
>= kColorWhichCount
) {
1157 fprintf(stderr
, "ui_color_name(): unknown color_which %d\n", which
);
1161 return kColorNames
[index
];
1166 which_ui_color(const char* name
)
1171 for (int32 index
= 0; index
< kColorWhichCount
; ++index
) {
1172 if (!strcmp(kColorNames
[index
], name
))
1173 return index_to_color_which(index
);
1181 set_ui_color(const color_which
&which
, const rgb_color
&color
)
1183 int32 index
= color_which_to_index(which
);
1184 if (index
< 0 || index
>= kColorWhichCount
) {
1185 fprintf(stderr
, "set_ui_color(): unknown color_which %d\n", which
);
1189 if (ui_color(which
) == color
)
1192 BPrivate::DesktopLink link
;
1193 link
.StartMessage(AS_SET_UI_COLOR
);
1194 link
.Attach
<color_which
>(which
);
1195 link
.Attach
<rgb_color
>(color
);
1201 set_ui_colors(const BMessage
* colors
)
1211 color_which which
= B_NO_COLOR
;
1213 BPrivate::DesktopLink desktop
;
1214 if (desktop
.InitCheck() != B_OK
)
1217 desktop
.StartMessage(AS_SET_UI_COLORS
);
1218 desktop
.Attach
<bool>(false);
1220 // Only colors with names that map to system colors will get through.
1221 while (colors
->GetInfo(B_RGB_32_BIT_TYPE
, index
, &name
, &type
) == B_OK
) {
1223 which
= which_ui_color(name
);
1226 if (which
== B_NO_COLOR
|| colors
->FindColor(name
, &color
) != B_OK
)
1229 desktop
.Attach
<color_which
>(which
);
1230 desktop
.Attach
<rgb_color
>(color
);
1237 desktop
.Attach
<color_which
>(B_NO_COLOR
);
1243 tint_color(rgb_color color
, float tint
)
1247 #define LIGHTEN(x) ((uint8)(255.0f - (255.0f - x) * tint))
1248 #define DARKEN(x) ((uint8)(x * (2 - tint)))
1251 result
.red
= LIGHTEN(color
.red
);
1252 result
.green
= LIGHTEN(color
.green
);
1253 result
.blue
= LIGHTEN(color
.blue
);
1254 result
.alpha
= color
.alpha
;
1256 result
.red
= DARKEN(color
.red
);
1257 result
.green
= DARKEN(color
.green
);
1258 result
.blue
= DARKEN(color
.blue
);
1259 result
.alpha
= color
.alpha
;
1269 rgb_color
shift_color(rgb_color color
, float shift
);
1272 shift_color(rgb_color color
, float shift
)
1274 return tint_color(color
, shift
);
1279 _init_interface_kit_()
1281 status_t status
= BPrivate::PaletteConverter::InitializeDefault(true);
1285 // init global clipboard
1286 if (be_clipboard
== NULL
)
1287 be_clipboard
= new BClipboard(NULL
);
1289 // TODO: Could support different themes here in the future.
1290 be_control_look
= new HaikuControlLook();
1292 _init_global_fonts_();
1294 BPrivate::gWidthBuffer
= new BPrivate::WidthBuffer
;
1295 status
= BPrivate::MenuPrivate::CreateBitmaps();
1299 _menu_info_ptr_
= &BMenu::sMenuInfo
;
1301 status
= get_menu_info(&BMenu::sMenuInfo
);
1305 general_info
.background_color
= ui_color(B_PANEL_BACKGROUND_COLOR
);
1306 general_info
.mark_color
= ui_color(B_CONTROL_MARK_COLOR
);
1307 general_info
.highlight_color
= ui_color(B_CONTROL_HIGHLIGHT_COLOR
);
1308 general_info
.window_frame_color
= ui_color(B_WINDOW_TAB_COLOR
);
1309 general_info
.color_frame
= true;
1311 // TODO: fill the other static members
1318 _fini_interface_kit_()
1320 BPrivate::MenuPrivate::DeleteBitmaps();
1322 delete BPrivate::gWidthBuffer
;
1323 BPrivate::gWidthBuffer
= NULL
;
1325 delete be_control_look
;
1326 be_control_look
= NULL
;
1328 // TODO: Anything else?
1335 namespace BPrivate
{
1338 /*! \brief queries the server for the current decorator
1339 \param ref entry_ref into which to store current decorator's location
1340 \return boolean true/false
1343 get_decorator(BString
& path
)
1345 BPrivate::AppServerLink link
;
1346 link
.StartMessage(AS_GET_DECORATOR
);
1349 if (link
.FlushWithReply(code
) != B_OK
|| code
!= B_OK
)
1352 return link
.ReadString(path
) == B_OK
;
1356 /*! \brief Private function which sets the window decorator for the system.
1357 \param entry_ref to the decorator to set
1359 Will return detailed error status via status_t
1362 set_decorator(const BString
& path
)
1364 BPrivate::AppServerLink link
;
1366 link
.StartMessage(AS_SET_DECORATOR
);
1368 link
.AttachString(path
.String());
1371 status_t error
= B_OK
;
1372 link
.Read
<status_t
>(&error
);
1378 /*! \brief sets a window to preview a given decorator
1379 \param path path to any given decorator add-on
1380 \param window pointer to BWindow which will show decorator
1382 Piggy-backs on BWindow::SetDecoratorSettings(...)
1385 preview_decorator(const BString
& path
, BWindow
* window
)
1390 BMessage
msg('prVu');
1391 msg
.AddString("preview", path
.String());
1393 return window
->SetDecoratorSettings(msg
);
1398 get_application_order(int32 workspace
, team_id
** _applications
,
1401 BPrivate::AppServerLink link
;
1403 link
.StartMessage(AS_GET_APPLICATION_ORDER
);
1404 link
.Attach
<int32
>(workspace
);
1407 status_t status
= link
.FlushWithReply(code
);
1414 link
.Read
<int32
>(&count
);
1416 *_applications
= (team_id
*)malloc(count
* sizeof(team_id
));
1417 if (*_applications
== NULL
)
1420 link
.Read(*_applications
, count
* sizeof(team_id
));
1427 get_window_order(int32 workspace
, int32
** _tokens
, int32
* _count
)
1429 BPrivate::AppServerLink link
;
1431 link
.StartMessage(AS_GET_WINDOW_ORDER
);
1432 link
.Attach
<int32
>(workspace
);
1435 status_t status
= link
.FlushWithReply(code
);
1442 link
.Read
<int32
>(&count
);
1444 *_tokens
= (int32
*)malloc(count
* sizeof(int32
));
1445 if (*_tokens
== NULL
)
1448 link
.Read(*_tokens
, count
* sizeof(int32
));
1454 } // namespace BPrivate
1456 // These methods were marked with "Danger, will Robinson!" in
1457 // the OpenTracker source, so we might not want to be compatible
1459 // In any way, we would need to update Deskbar to use our
1460 // replacements, so we could as well just implement them...
1463 do_window_action(int32 windowToken
, int32 action
, BRect zoomRect
, bool zoom
)
1465 BPrivate::AppServerLink link
;
1467 link
.StartMessage(AS_WINDOW_ACTION
);
1468 link
.Attach
<int32
>(windowToken
);
1469 link
.Attach
<int32
>(action
);
1470 // we don't have any zooming effect
1477 get_window_info(int32 serverToken
)
1479 BPrivate::AppServerLink link
;
1481 link
.StartMessage(AS_GET_WINDOW_INFO
);
1482 link
.Attach
<int32
>(serverToken
);
1485 if (link
.FlushWithReply(code
) != B_OK
|| code
!= B_OK
)
1489 link
.Read
<int32
>(&size
);
1491 client_window_info
* info
= (client_window_info
*)malloc(size
);
1495 link
.Read(info
, size
);
1501 get_token_list(team_id team
, int32
* _count
)
1503 BPrivate::AppServerLink link
;
1505 link
.StartMessage(AS_GET_WINDOW_LIST
);
1506 link
.Attach
<team_id
>(team
);
1509 if (link
.FlushWithReply(code
) != B_OK
|| code
!= B_OK
)
1513 link
.Read
<int32
>(&count
);
1515 int32
* tokens
= (int32
*)malloc(count
* sizeof(int32
));
1519 link
.Read(tokens
, count
* sizeof(int32
));
1526 do_bring_to_front_team(BRect zoomRect
, team_id team
, bool zoom
)
1528 BPrivate::AppServerLink link
;
1530 link
.StartMessage(AS_BRING_TEAM_TO_FRONT
);
1531 link
.Attach
<team_id
>(team
);
1532 // we don't have any zooming effect
1539 do_minimize_team(BRect zoomRect
, team_id team
, bool zoom
)
1541 BPrivate::AppServerLink link
;
1543 link
.StartMessage(AS_MINIMIZE_TEAM
);
1544 link
.Attach
<team_id
>(team
);
1545 // we don't have any zooming effect
1551 // #pragma mark - truncate string
1555 truncate_string(BString
& string
, uint32 mode
, float width
,
1556 const float* escapementArray
, float fontSize
, float ellipsisWidth
,
1559 // add a tiny amount to the width to make floating point inaccuracy
1560 // not drop chars that would actually fit exactly
1564 case B_TRUNCATE_BEGINNING
:
1566 float totalWidth
= 0;
1567 for (int32 i
= charCount
- 1; i
>= 0; i
--) {
1568 float charWidth
= escapementArray
[i
] * fontSize
;
1569 if (totalWidth
+ charWidth
> width
) {
1570 // we need to truncate
1571 while (totalWidth
+ ellipsisWidth
> width
) {
1572 // remove chars until there's enough space for the
1574 if (++i
== charCount
) {
1575 // we've reached the end of the string and still
1576 // no space, so return an empty string
1581 totalWidth
-= escapementArray
[i
] * fontSize
;
1584 string
.RemoveChars(0, i
+ 1);
1585 string
.PrependChars(B_UTF8_ELLIPSIS
, 1);
1589 totalWidth
+= charWidth
;
1595 case B_TRUNCATE_END
:
1597 float totalWidth
= 0;
1598 for (int32 i
= 0; i
< charCount
; i
++) {
1599 float charWidth
= escapementArray
[i
] * fontSize
;
1600 if (totalWidth
+ charWidth
> width
) {
1601 // we need to truncate
1602 while (totalWidth
+ ellipsisWidth
> width
) {
1603 // remove chars until there's enough space for the
1606 // we've reached the start of the string and still
1607 // no space, so return an empty string
1612 totalWidth
-= escapementArray
[i
] * fontSize
;
1615 string
.RemoveChars(i
, charCount
- i
);
1616 string
.AppendChars(B_UTF8_ELLIPSIS
, 1);
1620 totalWidth
+= charWidth
;
1626 case B_TRUNCATE_MIDDLE
:
1627 case B_TRUNCATE_SMART
:
1629 float leftWidth
= 0;
1630 float rightWidth
= 0;
1631 int32 leftIndex
= 0;
1632 int32 rightIndex
= charCount
- 1;
1635 for (int32 i
= 0; i
< charCount
; i
++) {
1637 = escapementArray
[left
? leftIndex
: rightIndex
] * fontSize
;
1639 if (leftWidth
+ rightWidth
+ charWidth
> width
) {
1640 // we need to truncate
1641 while (leftWidth
+ rightWidth
+ ellipsisWidth
> width
) {
1642 // remove chars until there's enough space for the
1644 if (leftIndex
== 0 && rightIndex
== charCount
- 1) {
1645 // we've reached both ends of the string and still
1646 // no space, so return an empty string
1651 if (leftIndex
> 0 && (rightIndex
== charCount
- 1
1652 || leftWidth
> rightWidth
)) {
1653 // remove char on the left
1654 leftWidth
-= escapementArray
[--leftIndex
]
1657 // remove char on the right
1658 rightWidth
-= escapementArray
[++rightIndex
]
1663 string
.RemoveChars(leftIndex
, rightIndex
+ 1 - leftIndex
);
1664 string
.InsertChars(B_UTF8_ELLIPSIS
, 1, leftIndex
);
1670 leftWidth
+= charWidth
;
1673 rightWidth
+= charWidth
;
1676 left
= rightWidth
> leftWidth
;
1683 // we've run through without the need to truncate, leave the string as it is