source: vendor/emx/current/src/pmgdb/threads.cc

Last change on this file was 18, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 9.2 KB
Line 
1/* threads.cc
2 Copyright (c) 1996 Eberhard Mattes
3
4This file is part of pmgdb.
5
6pmgdb is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11pmgdb is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with pmgdb; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21
22#define INCL_WIN
23#include <os2.h>
24#include <stdlib.h>
25#include <stdio.h> // sprintf()
26#include <stdarg.h>
27#include <string.h>
28#include <sys/ptrace.h>
29#include "string.h"
30#include "pmapp.h"
31#include "pmframe.h"
32#include "pmtxt.h"
33#include "pmtty.h"
34#include "pmgdb.h"
35#include "help.h"
36#include "breakpoi.h"
37#include "threads.h"
38#include "annotati.h"
39#include "gdbio.h"
40#include "command.h"
41
42
43class threads_window::thread
44{
45public:
46 thread () {}
47 ~thread () {}
48
49 thread *next;
50 int number;
51 int pid;
52 int line;
53 bool enable;
54};
55
56#define THR_HEADER_LINES 1
57
58threads_window::threads_window (command_window *in_cmd, gdbio *in_gdb,
59 unsigned in_id, const SWP *pswp,
60 const char *fontnamesize)
61 : pmtxt (in_cmd->get_app (), in_id,
62 pswp == NULL ? FCF_SHELLPOSITION : 0, pswp, fontnamesize)
63{
64 cmd = in_cmd; gdb = in_gdb;
65 head = NULL;
66 cur_line = -1; sel_line = -1;
67
68 sel_attr = get_default_attr ();
69 set_fg_color (sel_attr, CLR_BLACK);
70 set_bg_color (sel_attr, CLR_PALEGRAY);
71
72 hilite_attr = get_default_attr ();
73 set_fg_color (hilite_attr, CLR_WHITE);
74 set_bg_color (hilite_attr, CLR_BLACK);
75
76 sel_hilite_attr = get_default_attr ();
77 set_fg_color (sel_hilite_attr, CLR_WHITE);
78 set_bg_color (sel_hilite_attr, CLR_DARKGRAY);
79
80 menu_enable (IDM_EDITMENU, false);
81
82 int x = 0;
83 put (0, x, 6, " TID ", true); x += 6;
84 put_tab (0, x++, true);
85 put_vrule (0, x++, true);
86 put (0, x, 5, " Ena ", true); x += 5;
87 underline (0, true, true);
88
89 set_title ("pmgdb - Threads");
90 set_keys_help_id (HELP_THR_KEYS);
91}
92
93
94threads_window::~threads_window ()
95{
96 thread *p, *next;
97 for (p = head; p != NULL; p = next)
98 {
99 next = p->next;
100 delete p;
101 }
102}
103
104
105MRESULT threads_window::wm_activate (HWND hwnd, ULONG msg,
106 MPARAM mp1, MPARAM mp2)
107{
108 if (SHORT1FROMMP (mp1))
109 cmd->associate_help (get_hwndFrame ());
110 return WinDefWindowProc (hwnd, msg, mp1, mp2);
111}
112
113
114MRESULT threads_window::wm_close (HWND, ULONG, MPARAM, MPARAM)
115{
116 show (false);
117 return 0;
118}
119
120
121MRESULT threads_window::wm_command (HWND hwnd, ULONG msg,
122 MPARAM mp1, MPARAM mp2)
123{
124 const thread *p;
125
126 switch (SHORT1FROMMP (mp1))
127 {
128 case IDM_ENABLE:
129 p = find_by_line (sel_line);
130 if (p == NULL)
131 WinAlarm (HWND_DESKTOP, WA_ERROR);
132 else
133 gdb->send_cmd ("server thread enable %d", p->number);
134 break;
135
136 case IDM_DISABLE:
137 p = find_by_line (sel_line);
138 if (p == NULL)
139 WinAlarm (HWND_DESKTOP, WA_ERROR);
140 else
141 gdb->send_cmd ("server thread disable %d", p->number);
142 break;
143
144 case IDM_SWITCH:
145 p = find_by_line (sel_line);
146 if (p == NULL)
147 WinAlarm (HWND_DESKTOP, WA_ERROR);
148 else
149 gdb->send_cmd ("server thread %d", p->number);
150 break;
151
152 default:
153 return cmd->wm_command (hwnd, msg, mp1, mp2);
154 }
155 return WinDefWindowProc (hwnd, msg, mp1, mp2);
156}
157
158
159bool threads_window::wm_user (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
160{
161 if (parent::wm_user (hwnd, msg, mp1, mp2))
162 return true;
163 switch (msg)
164 {
165 case UWM_MENU:
166 if (sel_line == -1)
167 menu_enable (IDM_EDITMENU, false);
168 else
169 {
170 const thread *p = find_by_line (sel_line);
171 menu_enable (IDM_ENABLE, !p->enable);
172 menu_enable (IDM_DISABLE, p->enable);
173 }
174 return true;
175
176 default:
177 return false;
178 }
179}
180
181
182void threads_window::button_event (int line, int column, int tab, int button,
183 int clicks)
184{
185 if (line >= 0 && column >= 0)
186 {
187 // TODO: Context menu
188 if (button == 1 && clicks == 1)
189 select_line (line, true);
190 else if (button == 1 && clicks == 2 && tab == 1)
191 {
192 const thread *p = find_by_line (line);
193 if (p == NULL)
194 WinAlarm (HWND_DESKTOP, WA_ERROR);
195 else
196 gdb->send_cmd ("server thread %s %d",
197 p->enable ? "disable" : "enable", p->number);
198 }
199 else if (button == 1 && clicks == 2)
200 {
201 const thread *p = find_by_line (line);
202 if (p == NULL)
203 WinAlarm (HWND_DESKTOP, WA_ERROR);
204 else
205 {
206 gdb->call_cmd ("server thread %d", p->number);
207 cmd->where ();
208 }
209 }
210 }
211 else
212 select_line (-1);
213}
214
215
216threads_window::thread *threads_window::find_by_number (int number)
217{
218 for (thread *p = head; p != NULL; p = p->next)
219 if (p->number == number)
220 return p;
221 return NULL;
222}
223
224
225threads_window::thread *threads_window::find_by_line (int line)
226{
227 for (thread *p = head; p != NULL; p = p->next)
228 if (p->line == line)
229 return p;
230 return NULL;
231}
232
233
234void threads_window::add (int number, int pid)
235{
236 thread *p = find_by_number (number);
237 if (p == NULL)
238 {
239 int line = THR_HEADER_LINES;
240 thread **patch = &head;
241 while (*patch != NULL && (*patch)->pid < pid)
242 {
243 patch = &(*patch)->next;
244 ++line;
245 }
246 p = new thread;
247 p->next = *patch;
248 *patch = p;
249 p->number = number;
250 p->pid = pid;
251 p->line = line;
252 p->enable = true;
253 for (thread *q = p->next; q != NULL; q = q->next)
254 ++q->line;
255 insert_lines (p->line, 1, true);
256 if (cur_line != -1 && p->line <= cur_line)
257 ++cur_line;
258 if (sel_line != -1 && p->line <= sel_line)
259 ++sel_line;
260 update (p);
261 }
262}
263
264
265void threads_window::enable (int number)
266{
267 thread *p = find_by_number (number);
268 if (p != NULL && !p->enable)
269 {
270 p->enable = true;
271 if (p->line == sel_line)
272 WinPostMsg (get_hwndClient (), UWM_MENU, 0, 0);
273 update (p);
274 }
275}
276
277
278void threads_window::disable (int number)
279{
280 thread *p = find_by_number (number);
281 if (p != NULL && p->enable)
282 {
283 p->enable = false;
284 if (p->line == sel_line)
285 WinPostMsg (get_hwndClient (), UWM_MENU, 0, 0);
286 update (p);
287 }
288}
289
290
291void threads_window::remove (int pid)
292{
293 for (thread **patch = &head; *patch != NULL; patch = &(*patch)->next)
294 if ((*patch)->pid == pid)
295 {
296 for (thread *p = (*patch)->next; p != NULL; p = p->next)
297 --p->line;
298 thread *p = *patch;
299 delete_lines (p->line, 1, true);
300 *patch = p->next;
301 if (cur_line != -1 && p->line == cur_line)
302 cur_line = -1;
303 if (sel_line != -1 && p->line == sel_line)
304 {
305 sel_line = -1;
306 WinPostMsg (get_hwndClient (), UWM_MENU, 0, 0);
307 }
308 delete p;
309 return;
310 }
311}
312
313
314void threads_window::select (int number)
315{
316 thread *p = find_by_number (number);
317 if (p != NULL)
318 current_line (p->line);
319}
320
321
322void threads_window::update (const thread *p)
323{
324 char buf[400];
325 int x = 0, len;
326 pmtxt_attr attr;
327
328 if (p->line == cur_line && p->line == sel_line)
329 attr = sel_hilite_attr;
330 else if (p->line == cur_line)
331 attr = hilite_attr;
332 else if (p->line == sel_line)
333 attr = sel_attr;
334 else
335 attr = get_default_attr ();
336
337 clear_lines (p->line, 1, true);
338 len = snprintf (buf, sizeof (buf), " %d ", PTRACE_GETTID (p->pid));
339 put (p->line, x, len, buf, attr, true); x += len;
340 put_tab (p->line, x++, attr, true);
341 put_vrule (p->line, x++, attr, true);
342
343 len = snprintf (buf, sizeof (buf), " %c ", p->enable ? 'y' : 'n');
344 put (p->line, x, len, buf, attr, true); x += len;
345}
346
347
348void threads_window::current_line (int line)
349{
350 if (line != cur_line)
351 {
352 if (cur_line != -1)
353 put (cur_line, 0, max_line_len,
354 cur_line == sel_line ? sel_attr : get_default_attr (), true);
355 if (line != -1)
356 put (line, 0, max_line_len,
357 line == sel_line ? sel_hilite_attr : hilite_attr, true);
358 cur_line = line;
359 }
360}
361
362
363void threads_window::select_line (int line, bool toggle)
364{
365 const thread *p;
366 if (toggle && line != -1 && line == sel_line)
367 line = -1;
368 if (line == -1)
369 p = NULL;
370 else
371 {
372 p = find_by_line (line);
373 if (p == NULL) line = -1;
374 }
375 if (line != sel_line)
376 {
377 if (sel_line != -1)
378 put (sel_line, 0, max_line_len,
379 sel_line == cur_line ? hilite_attr : get_default_attr (), true);
380 if (line != -1)
381 put (line, 0, max_line_len,
382 line == cur_line ? sel_hilite_attr : sel_attr, true);
383 sel_line = line;
384 }
385 if (line != -1)
386 {
387 menu_enable (IDM_ENABLE, !p->enable);
388 menu_enable (IDM_DISABLE, p->enable);
389 show_line (line, 0, 0);
390 }
391 menu_enable (IDM_EDITMENU, line != -1);
392}
Note: See TracBrowser for help on using the repository browser.