xref: /haiku/src/apps/processcontroller/Utilities.cpp (revision 1acbe440b8dd798953bec31d18ee589aa3f71b73)
1 /*
2 	ProcessController © 2000, Georges-Edouard Berenger, All Rights Reserved.
3 	Copyright (C) 2004 beunited.org
4 
5 	This library is free software; you can redistribute it and/or
6 	modify it under the terms of the GNU Lesser General Public
7 	License as published by the Free Software Foundation; either
8 	version 2.1 of the License, or (at your option) any later version.
9 
10 	This library is distributed in the hope that it will be useful,
11 	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 	Lesser General Public License for more details.
14 
15 	You should have received a copy of the GNU Lesser General Public
16 	License along with this library; if not, write to the Free Software
17 	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18 */
19 
20 
21 #include "Utilities.h"
22 #include "PCWorld.h"
23 #include "ProcessController.h"
24 #include "icons.h"
25 
26 #include <Alert.h>
27 #include <Bitmap.h>
28 #include <Deskbar.h>
29 #include <FindDirectory.h>
30 #include <NodeInfo.h>
31 #include <Path.h>
32 #include <Roster.h>
33 #include <Screen.h>
34 #include <Window.h>
35 
36 #include <stdio.h>
37 #include <string.h>
38 
39 
40 bool
41 get_team_name_and_icon(info_pack& infoPack, bool icon)
42 {
43 	BPath systemPath;
44 	find_directory(B_BEOS_SYSTEM_DIRECTORY, &systemPath);
45 
46 	bool nameFromArgs = false;
47 	bool tryTrackerIcon = true;
48 
49 	for (int len = strlen(infoPack.team_info.args) - 1;
50 			len >= 0 && infoPack.team_info.args[len] == ' '; len--) {
51 		infoPack.team_info.args[len] = 0;
52 	}
53 
54 	app_info info;
55 	status_t status = be_roster->GetRunningAppInfo(infoPack.team_info.team, &info);
56 	if (status == B_OK || infoPack.team_info.team == B_SYSTEM_TEAM) {
57 		if (infoPack.team_info.team == B_SYSTEM_TEAM) {
58 			// Get icon and name from kernel
59 			system_info	systemInfo;
60 			get_system_info(&systemInfo);
61 
62 			BPath kernelPath(systemPath);
63 			kernelPath.Append(systemInfo.kernel_name);
64 			get_ref_for_path(kernelPath.Path(), &info.ref);
65 			nameFromArgs = true;
66 		}
67 	} else {
68 		BEntry entry(infoPack.team_info.args, true);
69 		status = entry.GetRef(&info.ref);
70 		if (status != B_OK
71 			|| strncmp(infoPack.team_info.args, systemPath.Path(),
72 				strlen(systemPath.Path())) != 0)
73 			nameFromArgs = true;
74 		tryTrackerIcon = (status == B_OK);
75 	}
76 
77 	strncpy(infoPack.team_name, nameFromArgs ? infoPack.team_info.args : info.ref.name,
78 		B_PATH_NAME_LENGTH - 1);
79 
80 	if (icon) {
81 #ifdef __HAIKU__
82 		infoPack.team_icon = new BBitmap(BRect(0, 0, 15, 15), B_RGBA32);
83 #else
84 		infoPack.team_icon = new BBitmap(BRect(0, 0, 15, 15), B_CMAP8);
85 #endif
86 		if (!tryTrackerIcon
87 			|| BNodeInfo::GetTrackerIcon(&info.ref, infoPack.team_icon,
88 				B_MINI_ICON) != B_OK) {
89 			// TODO: don't hardcode the "app" icon!
90 			infoPack.team_icon->SetBits(k_app_mini, 256, 0, B_CMAP8);
91 		}
92 	} else
93 		infoPack.team_icon = NULL;
94 
95 	return true;
96 }
97 
98 
99 bool
100 launch(const char* signature, const char* path)
101 {
102 	status_t status = be_roster->Launch(signature);
103 	if (status != B_OK && path) {
104 		entry_ref ref;
105 		if (get_ref_for_path(path, &ref) == B_OK)
106 			status = be_roster->Launch(&ref);
107 	}
108 	return status == B_OK;
109 }
110 
111 
112 void
113 mix_colors(rgb_color &target, rgb_color & first, rgb_color & second, float mix)
114 {
115 	target.red = (uint8)(second.red * mix + (1. - mix) * first.red);
116 	target.green = (uint8)(second.green * mix + (1. - mix) * first.green);
117 	target.blue = (uint8)(second.blue * mix + (1. - mix) * first.blue);
118 	target.alpha = (uint8)(second.alpha * mix + (1. - mix) * first.alpha);
119 }
120 
121 
122 void
123 find_self(entry_ref& ref)
124 {
125 	int32 cookie = 0;
126 	image_info info;
127 	while (get_next_image_info (0, &cookie, &info) == B_OK) {
128 		if (((uint32)info.text <= (uint32)move_to_deskbar
129 			&& (uint32)info.text + (uint32)info.text_size > (uint32)move_to_deskbar)
130 			|| ((uint32)info.data <= (uint32)move_to_deskbar
131 			&& (uint32)info.data + (uint32)info.data_size > (uint32)move_to_deskbar)) {
132 			if (get_ref_for_path (info.name, &ref) == B_OK)
133 				return;
134 		}
135 	}
136 
137 	// This works, but not always... :(
138 	app_info appInfo;
139 	be_roster->GetAppInfo(kSignature, &appInfo);
140 	ref = appInfo.ref;
141 }
142 
143 
144 void
145 move_to_deskbar(BDeskbar& deskbar)
146 {
147 	entry_ref ref;
148 	find_self(ref);
149 
150 	deskbar.AddItem(&ref);
151 }
152 
153 
154 void
155 make_window_visible(BWindow* window, bool mayResize)
156 {
157 	uint32 flags = window->Flags();
158 	BRect screen = BScreen(window).Frame();
159 	BRect frame = window->Frame();
160 	screen.InsetBy(4, 8);
161 	screen.OffsetBy(0, 8);
162 
163 	if (mayResize) {
164 		float width = frame.Width();
165 		float height = frame.Height();
166 		if (screen.Width() < width && !(flags & B_NOT_H_RESIZABLE))
167 			width = screen.Width();
168 		if (screen.Height() < height && !(flags & B_NOT_V_RESIZABLE))
169 			height = screen.Height();
170 		if (width != frame.Width() || height != frame.Height()) {
171 			window->ResizeTo(width, height);
172 			frame.right = frame.left + width;
173 			frame.bottom = frame.top + height;
174 		}
175 	}
176 	if (frame.right > screen.right)
177 		window->MoveBy(screen.right-frame.right, 0);
178 	if (frame.bottom > screen.bottom)
179 		window->MoveBy(0, screen.bottom-frame.bottom);
180 	if (frame.left < screen.left)
181 		window->MoveTo(screen.left, frame.top);
182 	if (frame.top < screen.top)
183 		window->MoveBy(0, screen.top-frame.top);
184 }
185 
186