home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / emxtutor.zip / emxsrcd1.zip / emx / src / pmgdb / threads.cc < prev    next >
C/C++ Source or Header  |  1996-09-08  |  10KB  |  393 lines

  1. /* threads.cc
  2.    Copyright (c) 1996 Eberhard Mattes
  3.  
  4. This file is part of pmgdb.
  5.  
  6. pmgdb is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. pmgdb is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with pmgdb; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 59 Temple Place - Suite 330,
  19. Boston, 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.  
  43. class threads_window::thread
  44. {
  45. public:
  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.  
  58. threads_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.  
  94. threads_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.  
  105. MRESULT 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.  
  114. MRESULT threads_window::wm_close (HWND, ULONG, MPARAM, MPARAM)
  115. {
  116.   show (false);
  117.   return 0;
  118. }
  119.  
  120.  
  121. MRESULT 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.  
  159. bool 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.  
  182. void 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.  
  216. threads_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.  
  225. threads_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.  
  234. void 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.  
  265. void 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.  
  278. void 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.  
  291. void 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.  
  314. void 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.  
  322. void 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.  
  348. void 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.  
  363. void 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. }
  393.