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>
14 /*! Global functions and variables for the Interface Kit */
17 #include <InterfaceDefs.h>
25 #include <Clipboard.h>
26 #include <ControlLook.h>
32 #include <ScrollBar.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
;
61 rgb_color highlight_color
;
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
106 {46, 204, 64, 255}, // B_SUCCESS_COLOR
107 {255, 65, 54, 255}, // B_FAILURE_COLOR
110 const rgb_color
* BPrivate::kDefaultColors
= &_kDefaultColors
[0];
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.
121 get_mode_parameter(uint32 mode
, int32
& width
, int32
& height
,
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
;
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
;
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
;
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
;
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;
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;
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;
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;
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;
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;
214 get_workspaces_layout(uint32
* _columns
, uint32
* _rows
)
219 BPrivate::AppServerLink link
;
220 link
.StartMessage(AS_GET_WORKSPACE_LAYOUT
);
223 if (link
.FlushWithReply(status
) == B_OK
&& status
== B_OK
) {
224 link
.Read
<int32
>(&columns
);
225 link
.Read
<int32
>(&rows
);
228 if (_columns
!= NULL
)
236 set_workspaces_layout(uint32 columns
, uint32 rows
)
238 if (columns
< 1 || rows
< 1)
241 BPrivate::AppServerLink link
;
242 link
.StartMessage(AS_SET_WORKSPACE_LAYOUT
);
243 link
.Attach
<int32
>(columns
);
244 link
.Attach
<int32
>(rows
);
249 } // namespace BPrivate
253 set_subpixel_antialiasing(bool subpix
)
255 BPrivate::AppServerLink link
;
257 link
.StartMessage(AS_SET_SUBPIXEL_ANTIALIASING
);
258 link
.Attach
<bool>(subpix
);
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
)
272 link
.Read
<bool>(subpix
);
278 set_hinting_mode(uint8 hinting
)
280 BPrivate::AppServerLink link
;
282 link
.StartMessage(AS_SET_HINTING
);
283 link
.Attach
<uint8
>(hinting
);
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
)
297 link
.Read
<uint8
>(hinting
);
303 set_average_weight(uint8 averageWeight
)
305 BPrivate::AppServerLink link
;
307 link
.StartMessage(AS_SET_SUBPIXEL_AVERAGE_WEIGHT
);
308 link
.Attach
<uint8
>(averageWeight
);
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
)
322 link
.Read
<uint8
>(averageWeight
);
328 set_is_subpixel_ordering_regular(bool subpixelOrdering
)
330 BPrivate::AppServerLink link
;
332 link
.StartMessage(AS_SET_SUBPIXEL_ORDERING
);
333 link
.Attach
<bool>(subpixelOrdering
);
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
)
347 link
.Read
<bool>(subpixelOrdering
);
355 return BScreen(B_MAIN_SCREEN_ID
).ColorMap();
360 set_screen_space(int32 index
, uint32 space
, bool stick
)
365 if (!BPrivate::get_mode_parameter(space
, width
, height
, depth
))
368 BScreen
screen(B_MAIN_SCREEN_ID
);
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
);
378 mode
.virtual_width
= width
;
379 mode
.virtual_height
= height
;
382 return screen
.SetMode(index
, &mode
, stick
);
387 get_scroll_bar_info(scroll_bar_info
*info
)
392 BPrivate::AppServerLink link
;
393 link
.StartMessage(AS_GET_SCROLLBAR_INFO
);
396 if (link
.FlushWithReply(code
) == B_OK
398 link
.Read
<scroll_bar_info
>(info
);
407 set_scroll_bar_info(scroll_bar_info
*info
)
412 BPrivate::AppServerLink link
;
415 link
.StartMessage(AS_SET_SCROLLBAR_INFO
);
416 link
.Attach
<scroll_bar_info
>(*info
);
418 if (link
.FlushWithReply(code
) == B_OK
427 get_mouse_type(int32
*type
)
429 BMessage
command(IS_GET_MOUSE_TYPE
);
432 status_t err
= _control_input_server_(&command
, &reply
);
435 return reply
.FindInt32("mouse_type", type
);
440 set_mouse_type(int32 type
)
442 BMessage
command(IS_SET_MOUSE_TYPE
);
445 status_t err
= command
.AddInt32("mouse_type", type
);
448 return _control_input_server_(&command
, &reply
);
453 get_mouse_map(mouse_map
*map
)
455 BMessage
command(IS_GET_MOUSE_MAP
);
457 const void *data
= 0;
460 status_t err
= _control_input_server_(&command
, &reply
);
462 err
= reply
.FindData("mousemap", B_RAW_TYPE
, &data
, &count
);
466 memcpy(map
, data
, count
);
473 set_mouse_map(mouse_map
*map
)
475 BMessage
command(IS_SET_MOUSE_MAP
);
478 status_t err
= command
.AddData("mousemap", B_RAW_TYPE
, map
,
482 return _control_input_server_(&command
, &reply
);
487 get_click_speed(bigtime_t
*speed
)
489 BMessage
command(IS_GET_CLICK_SPEED
);
492 status_t err
= _control_input_server_(&command
, &reply
);
496 if (reply
.FindInt64("speed", speed
) != B_OK
)
504 set_click_speed(bigtime_t speed
)
506 BMessage
command(IS_SET_CLICK_SPEED
);
508 command
.AddInt64("speed", speed
);
509 return _control_input_server_(&command
, &reply
);
514 get_mouse_speed(int32
*speed
)
516 BMessage
command(IS_GET_MOUSE_SPEED
);
519 status_t err
= _control_input_server_(&command
, &reply
);
523 if (reply
.FindInt32("speed", speed
) != B_OK
)
531 set_mouse_speed(int32 speed
)
533 BMessage
command(IS_SET_MOUSE_SPEED
);
535 command
.AddInt32("speed", speed
);
536 return _control_input_server_(&command
, &reply
);
541 get_mouse_acceleration(int32
*speed
)
543 BMessage
command(IS_GET_MOUSE_ACCELERATION
);
546 _control_input_server_(&command
, &reply
);
548 if (reply
.FindInt32("speed", speed
) != B_OK
)
556 set_mouse_acceleration(int32 speed
)
558 BMessage
command(IS_SET_MOUSE_ACCELERATION
);
560 command
.AddInt32("speed", speed
);
561 return _control_input_server_(&command
, &reply
);
566 get_key_repeat_rate(int32
*rate
)
568 BMessage
command(IS_GET_KEY_REPEAT_RATE
);
571 _control_input_server_(&command
, &reply
);
573 if (reply
.FindInt32("rate", rate
) != B_OK
)
581 set_key_repeat_rate(int32 rate
)
583 BMessage
command(IS_SET_KEY_REPEAT_RATE
);
585 command
.AddInt32("rate", rate
);
586 return _control_input_server_(&command
, &reply
);
591 get_key_repeat_delay(bigtime_t
*delay
)
593 BMessage
command(IS_GET_KEY_REPEAT_DELAY
);
596 _control_input_server_(&command
, &reply
);
598 if (reply
.FindInt64("delay", delay
) != B_OK
)
606 set_key_repeat_delay(bigtime_t delay
)
608 BMessage
command(IS_SET_KEY_REPEAT_DELAY
);
610 command
.AddInt64("delay", delay
);
611 return _control_input_server_(&command
, &reply
);
618 BMessage
command(IS_GET_MODIFIERS
);
622 _control_input_server_(&command
, &reply
);
624 if (reply
.FindInt32("status", &err
) != B_OK
)
627 if (reply
.FindInt32("modifiers", &modifier
) != B_OK
)
635 get_key_info(key_info
*info
)
637 BMessage
command(IS_GET_KEY_INFO
);
639 const void *data
= 0;
643 _control_input_server_(&command
, &reply
);
645 if (reply
.FindInt32("status", &err
) != B_OK
)
648 if (reply
.FindData("key_info", B_ANY_TYPE
, &data
, &count
) != B_OK
)
651 memcpy(info
, data
, count
);
657 get_key_map(key_map
**map
, char **key_buffer
)
659 _get_key_map(map
, key_buffer
, NULL
);
664 _get_key_map(key_map
**map
, char **key_buffer
, ssize_t
*key_buffer_size
)
666 BMessage
command(IS_GET_KEY_MAP
);
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;
680 if (reply
.FindData("key_buffer", B_ANY_TYPE
, &key_array
, key_buffer_size
)
682 *map
= 0; *key_buffer
= 0;
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
);
694 get_keyboard_id(uint16
*id
)
696 BMessage
command(IS_GET_KEYBOARD_ID
);
700 _control_input_server_(&command
, &reply
);
702 status_t err
= reply
.FindInt16("id", (int16
*)&kid
);
712 get_modifier_key(uint32 modifier
, uint32
*key
)
714 BMessage
command(IS_GET_MODIFIER_KEY
);
718 command
.AddInt32("modifier", modifier
);
719 _control_input_server_(&command
, &reply
);
721 status_t err
= reply
.FindInt32("key", (int32
*) &rkey
);
731 set_modifier_key(uint32 modifier
, uint32 key
)
733 BMessage
command(IS_SET_MODIFIER_KEY
);
736 command
.AddInt32("modifier", modifier
);
737 command
.AddInt32("key", key
);
738 _control_input_server_(&command
, &reply
);
743 set_keyboard_locks(uint32 modifiers
)
745 BMessage
command(IS_SET_KEYBOARD_LOCKS
);
748 command
.AddInt32("locks", modifiers
);
749 _control_input_server_(&command
, &reply
);
756 BMessage
message(IS_RESTORE_KEY_MAP
);
759 return _control_input_server_(&message
, &reply
);
764 keyboard_navigation_color()
766 // Queries the app_server
767 return ui_color(B_KEYBOARD_NAVIGATION_COLOR
);
776 BPrivate::get_workspaces_layout(&columns
, &rows
);
778 return columns
* rows
;
783 set_workspace_count(int32 count
)
785 int32 squareRoot
= (int32
)sqrt(count
);
788 for (int32 i
= 2; i
<= squareRoot
; i
++) {
793 int32 columns
= count
/ rows
;
795 BPrivate::set_workspaces_layout(columns
, rows
);
804 BPrivate::AppServerLink link
;
805 link
.StartMessage(AS_CURRENT_WORKSPACE
);
808 if (link
.FlushWithReply(status
) == B_OK
&& status
== B_OK
)
809 link
.Read
<int32
>(&index
);
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);
829 bigtime_t idletime
= 0;
831 BPrivate::AppServerLink link
;
832 link
.StartMessage(AS_IDLE_TIME
);
835 if (link
.FlushWithReply(code
) == B_OK
&& code
== B_OK
)
836 link
.Read
<int64
>(&idletime
);
843 run_select_printer_panel()
845 if (be_roster
== NULL
)
848 // Launches the Printer prefs app via the Roster
849 be_roster
->Launch(PRNT_SIGNATURE_TYPE
);
854 run_add_printer_panel()
856 // Launches the Printer prefs app via the Roster and asks it to
858 run_select_printer_panel();
860 BMessenger
printerPanelMessenger(PRNT_SIGNATURE_TYPE
);
861 printerPanelMessenger
.SendMessage(PRINTERS_ADD_PRINTER
);
868 if (be_roster
!= NULL
)
869 be_roster
->Launch("application/x-vnd.Haiku-About");
874 set_focus_follows_mouse(bool follow
)
876 // obviously deprecated API
877 set_mouse_mode(B_FOCUS_FOLLOWS_MOUSE
);
882 focus_follows_mouse()
884 return mouse_mode() == B_FOCUS_FOLLOWS_MOUSE
;
889 set_mouse_mode(mode_mouse mode
)
891 BPrivate::AppServerLink link
;
892 link
.StartMessage(AS_SET_MOUSE_MODE
);
893 link
.Attach
<mode_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
);
909 if (link
.FlushWithReply(code
) == B_OK
&& code
== B_OK
)
910 link
.Read
<mode_mouse
>(&mode
);
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
);
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
);
935 if (link
.FlushWithReply(code
) == B_OK
&& code
== B_OK
)
936 link
.Read
<mode_focus_follows_mouse
>(&mode
);
943 get_mouse(BPoint
* screenWhere
, uint32
* buttons
)
945 if (screenWhere
== NULL
&& buttons
== NULL
)
948 BPrivate::AppServerLink link
;
949 link
.StartMessage(AS_GET_CURSOR_POSITION
);
952 status_t ret
= link
.FlushWithReply(code
);
958 if (screenWhere
!= NULL
)
959 ret
= link
.Read
<BPoint
>(screenWhere
);
962 ret
= link
.Read
<BPoint
>(&dummy
);
968 ret
= link
.Read
<uint32
>(buttons
);
971 ret
= link
.Read
<uint32
>(&dummy
);
979 get_mouse_bitmap(BBitmap
** bitmap
, BPoint
* hotspot
)
981 if (bitmap
== NULL
&& hotspot
== NULL
)
984 BPrivate::AppServerLink link
;
985 link
.StartMessage(AS_GET_CURSOR_BITMAP
);
988 status_t status
= link
.FlushWithReply(code
);
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
) {
1005 link
.Read
<BPoint
>(&dummy
);
1007 link
.Read
<BPoint
>(hotspot
);
1011 data
= malloc(size
);
1015 status
= link
.Read(data
, size
);
1016 if (status
!= B_OK
) {
1021 BBitmap
* cursorBitmap
= new (std::nothrow
) BBitmap(BRect(0, 0,
1022 cursorWidth
- 1, cursorHeight
- 1), B_RGBA32
);
1024 if (cursorBitmap
== NULL
) {
1028 status
= cursorBitmap
->InitCheck();
1030 cursorBitmap
->SetBits(data
, size
, 0, B_RGBA32
);
1034 if (status
== B_OK
&& bitmap
!= NULL
)
1035 *bitmap
= cursorBitmap
;
1037 delete cursorBitmap
;
1044 set_accept_first_click(bool acceptFirstClick
)
1046 BPrivate::AppServerLink link
;
1047 link
.StartMessage(AS_SET_ACCEPT_FIRST_CLICK
);
1048 link
.Attach
<bool>(acceptFirstClick
);
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
);
1063 if (link
.FlushWithReply(code
) == B_OK
&& code
== B_OK
)
1064 link
.Read
<bool>(&acceptFirstClick
);
1066 return acceptFirstClick
;
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();
1083 return shared
->colors
[index
];
1086 return kDefaultColors
[index
];
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
);
1099 BPrivate::AppServerLink link
;
1100 link
.StartMessage(AS_SET_UI_COLOR
);
1101 link
.Attach
<color_which
>(which
);
1102 link
.Attach
<rgb_color
>(color
);
1108 tint_color(rgb_color color
, float tint
)
1112 #define LIGHTEN(x) ((uint8)(255.0f - (255.0f - x) * tint))
1113 #define DARKEN(x) ((uint8)(x * (2 - tint)))
1116 result
.red
= LIGHTEN(color
.red
);
1117 result
.green
= LIGHTEN(color
.green
);
1118 result
.blue
= LIGHTEN(color
.blue
);
1119 result
.alpha
= color
.alpha
;
1121 result
.red
= DARKEN(color
.red
);
1122 result
.green
= DARKEN(color
.green
);
1123 result
.blue
= DARKEN(color
.blue
);
1124 result
.alpha
= color
.alpha
;
1134 rgb_color
shift_color(rgb_color color
, float shift
);
1137 shift_color(rgb_color color
, float shift
)
1139 return tint_color(color
, shift
);
1144 _init_interface_kit_()
1146 status_t status
= BPrivate::PaletteConverter::InitializeDefault(true);
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();
1164 _menu_info_ptr_
= &BMenu::sMenuInfo
;
1166 status
= get_menu_info(&BMenu::sMenuInfo
);
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
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?
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
1208 get_decorator(BString
& path
)
1210 BPrivate::AppServerLink link
;
1211 link
.StartMessage(AS_GET_DECORATOR
);
1214 if (link
.FlushWithReply(code
) != B_OK
|| code
!= B_OK
)
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
1227 set_decorator(const BString
& path
)
1229 BPrivate::AppServerLink link
;
1231 link
.StartMessage(AS_SET_DECORATOR
);
1233 link
.AttachString(path
.String());
1236 status_t error
= B_OK
;
1237 link
.Read
<status_t
>(&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(...)
1250 preview_decorator(const BString
& path
, BWindow
* window
)
1255 BMessage
msg('prVu');
1256 msg
.AddString("preview", path
.String());
1258 return window
->SetDecoratorSettings(msg
);
1263 get_application_order(int32 workspace
, team_id
** _applications
,
1266 BPrivate::AppServerLink link
;
1268 link
.StartMessage(AS_GET_APPLICATION_ORDER
);
1269 link
.Attach
<int32
>(workspace
);
1272 status_t status
= link
.FlushWithReply(code
);
1279 link
.Read
<int32
>(&count
);
1281 *_applications
= (team_id
*)malloc(count
* sizeof(team_id
));
1282 if (*_applications
== NULL
)
1285 link
.Read(*_applications
, count
* sizeof(team_id
));
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
);
1300 status_t status
= link
.FlushWithReply(code
);
1307 link
.Read
<int32
>(&count
);
1309 *_tokens
= (int32
*)malloc(count
* sizeof(int32
));
1310 if (*_tokens
== NULL
)
1313 link
.Read(*_tokens
, count
* sizeof(int32
));
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
1324 // In any way, we would need to update Deskbar to use our
1325 // replacements, so we could as well just implement them...
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
1342 get_window_info(int32 serverToken
)
1344 BPrivate::AppServerLink link
;
1346 link
.StartMessage(AS_GET_WINDOW_INFO
);
1347 link
.Attach
<int32
>(serverToken
);
1350 if (link
.FlushWithReply(code
) != B_OK
|| code
!= B_OK
)
1354 link
.Read
<int32
>(&size
);
1356 client_window_info
* info
= (client_window_info
*)malloc(size
);
1360 link
.Read(info
, size
);
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
);
1374 if (link
.FlushWithReply(code
) != B_OK
|| code
!= B_OK
)
1378 link
.Read
<int32
>(&count
);
1380 int32
* tokens
= (int32
*)malloc(count
* sizeof(int32
));
1384 link
.Read(tokens
, count
* sizeof(int32
));
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
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
1416 // #pragma mark - truncate string
1420 truncate_string(BString
& string
, uint32 mode
, float width
,
1421 const float* escapementArray
, float fontSize
, float ellipsisWidth
,
1424 // add a tiny amount to the width to make floating point inaccuracy
1425 // not drop chars that would actually fit exactly
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
1439 if (++i
== charCount
) {
1440 // we've reached the end of the string and still
1441 // no space, so return an empty string
1446 totalWidth
-= escapementArray
[i
] * fontSize
;
1449 string
.RemoveChars(0, i
+ 1);
1450 string
.PrependChars(B_UTF8_ELLIPSIS
, 1);
1454 totalWidth
+= charWidth
;
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
1471 // we've reached the start of the string and still
1472 // no space, so return an empty string
1477 totalWidth
-= escapementArray
[i
] * fontSize
;
1480 string
.RemoveChars(i
, charCount
- i
);
1481 string
.AppendChars(B_UTF8_ELLIPSIS
, 1);
1485 totalWidth
+= charWidth
;
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;
1500 for (int32 i
= 0; i
< charCount
; i
++) {
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
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
1516 if (leftIndex
> 0 && (rightIndex
== charCount
- 1
1517 || leftWidth
> rightWidth
)) {
1518 // remove char on the left
1519 leftWidth
-= escapementArray
[--leftIndex
]
1522 // remove char on the right
1523 rightWidth
-= escapementArray
[++rightIndex
]
1528 string
.RemoveChars(leftIndex
, rightIndex
+ 1 - leftIndex
);
1529 string
.InsertChars(B_UTF8_ELLIPSIS
, 1, leftIndex
);
1535 leftWidth
+= charWidth
;
1538 rightWidth
+= charWidth
;
1541 left
= rightWidth
> leftWidth
;
1548 // we've run through without the need to truncate, leave the string as it is