--------------------------------------------------------------------- ----------- ------------------------------------------------------------------------------ -- Cheddar is a GNU GPL real time scheduling analysis tool. -- This program provides services to automatically check performances -- of real time architectures. -- -- Copyright (C) 2002-2010, by Frank Singhoff, Alain Plantec, Jerome Legrand -- -- The Cheddar project was started in 2002 by -- the LISyC Team, University of Western Britanny. -- -- Since 2008, Ellidiss technologies also contributes to the development of -- Cheddar and provides industrial support. -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program; if not, write to the Free Software -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -- -- -- Contact : cheddar@listes.univ-brest.fr -- ----------------------------------------------------------------------------- -- Last update : -- $Rev: 523 $ -- $Date: 2012-09-26 15:09:39 +0200 (mer. 26 sept. 2012) $ -- $Author: fotsing $ ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ with Gdk.Drawable; use Gdk.Drawable; with Gdk.font; use Gdk.font; with Gtk.Arguments; use Gtk.Arguments; with Gtk.Drawing_Area; use Gtk.Drawing_Area; with Gtk.Handlers; use Gtk.Handlers; with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; with Processor_Set; use Processor_Set; use Processor_Set.Generic_Processor_Set; with Tasks; use Tasks; with Resources; use Resources; with Messages; use Messages; with Buffers; use Buffers; with Time_Unit_Events; use Time_Unit_Events; use Time_Unit_Events.Time_Unit_Package; with unbounded_strings; use unbounded_strings; --with Events; use Events; with time_unit_events.extended; use time_unit_events.extended; with Framework_Config; use Framework_Config; with Translate; use Translate; with graphical_editor.Select_Time_Line_Pkg; use graphical_editor.Select_Time_Line_Pkg; with Select_Time_Line_Interface; use Select_Time_Line_Interface; use Select_Time_Line_Interface.Generic_Time_Line_Object_Set; with Objects; use Objects; with Editor_Config; use Editor_Config; with Text_IO; use Text_IO; with graphical_editor.scheduling_simulation_callbacks; use graphical_editor.scheduling_simulation_callbacks; --with test_area_pkg; use test_area_pkg; with Gdk.Window; use Gdk.Window; with Gdk.Color; use Gdk.Color; with pango.font; use pango.font; package body graphical_editor.Draw_Scheduling_Pkg is --package Draw_Cb is new Gtk.Handlers.Return_Callback ( -- Widget_Type => Gtk_Double_Buffer_Record, --Return_Type => Boolean); -- package Cb is new -- Gtk.Handlers.Callback(Gtk.Drawing_Area.Gtk_Drawing_Area_Record); use Cb; --Connect (Gtk_Drawing_Area(my_area), "expose_event", To_Marshaller(Expose'Access)); -- the callback proc for expose_event --procedure Expose (W : access Gtk.Drawing_Area.Gtk_Drawing_Area_Record'Class) -- is --begin --Draw_Time_Line_cbk; -- end Expose; --voir comment gerer configure event et size allocate -- package Allocation_Cb is new Handlers.Callback (Gtk_Double_Buffer_Record); --package Allocation_Marshaller is new -- Allocation_Cb.Marshallers.Generic_Marshaller ( -- Gtk_Allocation_Access, -- To_Allocation); procedure Color_Allocation (Draw_Scheduling : access Draw_Scheduling_Record) is begin if not Draw_Scheduling.Have_Colors then Gdk.GC.Gdk_New (Draw_Scheduling.White_Gc, Get_window(my_area)); Gdk.GC.Set_Foreground (Draw_Scheduling.White_Gc, Gdk.Color.White (Gtk.Widget.Get_Default_Colormap)); Gdk.GC.Gdk_New (Draw_Scheduling.Black_Gc, Get_window(my_area)); Gdk.GC.Set_Foreground (Draw_Scheduling.Black_Gc, Gdk.Color.Black (Gtk.Widget.Get_Default_Colormap)); Draw_Scheduling.Red_Color := Gdk.Color.Parse ("Red"); Gdk.Color.Alloc (Gtk.Widget.Get_Default_Colormap, Draw_Scheduling.Red_Color); Draw_Scheduling.Blue_Color := Gdk.Color.Parse ("Blue"); Gdk.Color.Alloc (Gtk.Widget.Get_Default_Colormap, Draw_Scheduling.Blue_Color); Draw_Scheduling.Have_Colors := True; end if; end Color_Allocation; -- function Configure -- (Buffer : access Gtk_Double_Buffer_Record'Class; -- Event : Gdk.Event.Gdk_Event) -- return Boolean -- is -- begin -- if Draw_Scheduling.Initialized then -- Redraw_Time_Line (Draw_Scheduling); -- else --Color_Allocation (Draw_Scheduling); -- Check if window size has changed ! -- -- Draw_Scheduling.Current_Width := --Gint (Get_Allocation_Width (Draw_Scheduling.Buffer)); --Draw_Scheduling.Current_Height := -- Gint (Get_Allocation_Height (Draw_Scheduling.Buffer)); -- Draw_Rectangle -- (--Get_Pixmap (Draw_Scheduling.Buffer), -- get_window(my_area), -- Draw_Scheduling.White_Gc, -- Filled => True, --X => 0, --Y => 0, -- Width => Draw_Scheduling.Current_Width, -- Height => Draw_Scheduling.Current_Height); -- Double_Buffer.Draw (Draw_Scheduling.Buffer); --end if; -- return True; --end Configure; -- This function is called once gtk has decided what size and position -- the widget will actually have, or everytime the widget is resized. -- This would be a good time for instance for resizing the component -- sub-widgets. -- Note that we have to move and resize the widget ourselves, and that -- for such a simple case, we could simply rely on the ancestor's -- size_allocation function. -- -- procedure Size_Allocate -- (Buffer : access Gtk_Double_Buffer_Record'Class; -- Allocation : Gtk_Allocation_Access) --is -- begin -- if Realized_Is_Set (Buffer) then -- Draw_Scheduling.Current_Width := -- Gint (Get_Allocation_Width (Draw_Scheduling.Buffer)); -- Draw_Scheduling.Current_Height := -- Gint (Get_Allocation_Height (Draw_Scheduling.Buffer)); -- if Draw_Scheduling.Initialized then -- Redraw_Time_Line (Draw_Scheduling); --else -- Color_Allocation (Draw_Scheduling); -- Draw_Rectangle -- (Get_Pixmap (Draw_Scheduling.Buffer), --Draw_Scheduling.White_Gc, -- Filled => True, -- X => 0, -- Y => 0, -- Width => Draw_Scheduling.Current_Width, -- Height => Draw_Scheduling.Current_Height); -- Double_Buffer.Draw (Draw_Scheduling.Buffer); -- end if; -- end if; -- Gtk.Handlers.Emit_Stop_By_Name (Buffer, "size_allocate"); -- end Size_Allocate; procedure Gtk_New (Draw_Scheduling : out Draw_Scheduling_Access) is begin Draw_Scheduling := new Draw_Scheduling_Record; graphical_editor.Draw_Scheduling_Pkg.Initialize (Draw_Scheduling); end Gtk_New; procedure Initialize (Draw_Scheduling : access Draw_Scheduling_Record'Class) is begin --Draw_Scheduling.Current_Width := Draw_Scheduling.First_Width; -- Draw_Scheduling.Current_Height := Draw_Scheduling.First_Height; --Gtk_New (Draw_Scheduling.Buffer); --j'essaye l'option sans double buffer -- Gtk.Drawing_Area.Set_USize --(Gtk_Drawing_Area (Draw_Scheduling.Buffer), -- Draw_Scheduling.First_Width, -- Draw_Scheduling.First_Height); --en principe le drawing area est deja dessine --Gtk.Drawing_Area.Size -- (Gtk_Drawing_Area (Draw_Scheduling.Buffer), -- Draw_Scheduling.First_Width, -- Draw_Scheduling.First_Height); -- Show_All (Draw_Scheduling.Buffer); --Load --(Draw_Scheduling.Font, --"-adobe-helvetica-medium-o-normal--14-140-75-75-p-78-iso8859-1"); --"-*-courier-medium-r-normal-*-*-160-*-*-*-*-*-*"); --Draw_Scheduling.Font := From_Description (From_String("Courier 12")); Draw_Scheduling.Font := From_Description (From_String("-adobe-helvetica-medium-o-normal--14-140-75-75-p-78-iso8859-1")); --je gere le configure event --avec mes callbacks ... je dois reecrire tout ce module, afin de gerer aussi le size allocate ... -- Draw_Cb.Connect -- (Draw_Scheduling.Buffer, -- "configure_event", -- Draw_Cb.To_Marshaller (Configure'Access)); --voir comment gerer avec la nouvelle approche le size'allocate ... -- Allocation_Cb.Connect --(Draw_Scheduling.Buffer, -- "size_allocate", -- Allocation_Marshaller.To_Marshaller (Size_Allocate'Access)); end Initialize; procedure Draw_Time_Line_Axis (Draw_Scheduling : access Draw_Scheduling_Record; Line_Number : in Gint) is begin Draw_Line (--Get_Pixmap (Draw_Scheduling.Buffer), get_window(my_area), Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin, Draw_Scheduling.High_Margin + Line_Number * Draw_Scheduling.Interligne, Draw_Scheduling.Left_Margin + Gint (Draw_Scheduling.Period - Draw_Scheduling.Start_Draw) * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + Line_Number * Draw_Scheduling.Interligne); -- For each line, draw unit time lines -- for J in 0 .. Gint (Draw_Scheduling.Period - Draw_Scheduling.Start_Draw) loop Draw_Line (--Get_Pixmap (Draw_Scheduling.Buffer), get_window(my_area), Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin + J * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + Line_Number * Draw_Scheduling.Interligne - 3, Draw_Scheduling.Left_Margin + J * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + Line_Number * Draw_Scheduling.Interligne + 3); if J mod Gint (Display_Witch_Time_Unit_Label) = 0 then Draw_Text ( get_window(my_area), Draw_Scheduling.Font, Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin + J * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + Line_Number * Draw_Scheduling.Interligne + Draw_Scheduling.Interligne / 2, Gint'Image (J)); Gdk.GC.Set_Foreground (Draw_Scheduling.Black_Gc, Gdk.Color.Black (Gtk.Widget.Get_Default_Colormap)); Draw_Rectangle ( get_window(my_area), Draw_Scheduling.Black_Gc, True, Draw_Scheduling.Left_Margin + Draw_Scheduling.Timeunit_Margin * J, Draw_Scheduling.High_Margin + Line_Number * Draw_Scheduling.Interligne - 8, 3, 16); end if; end loop; end Draw_Time_Line_Axis; procedure Clear_Time_Line (Draw_Scheduling : access Draw_Scheduling_Record) is begin Color_Allocation (Draw_Scheduling); Draw_Scheduling.Initialized := False; Draw_Rectangle (get_window(my_area), Draw_Scheduling.White_Gc, Filled => True, X => 0, Y => 0, Width => Draw_Scheduling.Current_Width, Height => Draw_Scheduling.Current_Height); -- Double_Buffer.Draw (Draw_Scheduling.Buffer); end Clear_Time_Line; procedure Draw_Time_Line (--Object : access Gtkada_Builder_Record'Class; Draw_Scheduling : access Draw_Scheduling_Record; Task1 : Tasks_Set; Resource1 : Resources_Set; Message1 : Messages_Set; Buffer1 : Buffers_Set; Period1 : Natural; Start_Draw1 : Natural; Sched1 : Scheduling_Table_Ptr) is I : Gint := 0; Ok : Boolean; Number_of_time_axis : Gint := 0; --pragma Unreferenced (Object); begin -- Draw_Scheduling.Buffer := Gtk_Double_Buffer(my_area); Draw_Scheduling.Tasks := Task1; Draw_Scheduling.Resources := Resource1; Draw_Scheduling.Messages := Message1; Draw_Scheduling.Buffers := Buffer1; Draw_Scheduling.Period := Period1; Draw_Scheduling.Start_Draw := Start_Draw1; Draw_Scheduling.Sched := Sched1; -- Set Left_margin -- Draw_Scheduling.Left_Margin := 20; -- Compute Widget size -- Ok := False; I := Gint (Period1 - Start_Draw1) * Draw_Scheduling.Timeunit_Margin + Draw_Scheduling.Left_Margin + Draw_Scheduling.Right_Margin; if I > Draw_Scheduling.Current_Width then Draw_Scheduling.Current_Width := I; Ok := True; end if; if is_empty (Time_Line_To_Display) then I := Draw_Scheduling.High_Margin + Draw_Scheduling.Interligne * Gint (get_number_of_elements (Task1)); Number_of_time_axis := Number_of_time_axis + Gint (get_number_of_elements (Task1)); if Schedule_With_Resources then I := I + Draw_Scheduling.Interligne * Gint (get_number_of_elements (Resource1)); Number_of_time_axis := Number_of_time_axis + Gint (get_number_of_elements (Resource1)); end if; if Schedule_With_Precedencies then I := I + Draw_Scheduling.Interligne * Gint (get_number_of_elements (Buffer1)); I := I + Draw_Scheduling.Interligne * Gint (get_number_of_elements (Message1)); Number_of_time_axis := Number_of_time_axis + Gint (get_number_of_elements (Message1)) + Gint (get_number_of_elements (Buffer1)); end if; else I := Draw_Scheduling.Interligne * Gint (get_number_of_elements (Time_Line_To_Display)); Number_of_time_axis := Number_of_time_axis + Gint (get_number_of_elements (Time_Line_To_Display)); end if; -- Take care of Time line Axis -- We need some extra lines to display time axis lines -- Number_of_time_axis := (Number_of_time_axis / Gint (Time_Line_Between_Time_Axis)) + 1; I := I + Draw_Scheduling.Interligne * Number_of_time_axis; if I > Draw_Scheduling.Current_Height then Draw_Scheduling.Current_Height := I; Ok := True; end if; if Ok then Gtk.Drawing_Area.Set_USize (Gtk_Drawing_Area(my_area), Draw_Scheduling.Current_Width, Draw_Scheduling.Current_Height); end if; Draw_Scheduling.Initialized := True; --my_Redraw_Time_Line (Draw_Scheduling); Redraw_Time_Line (Draw_Scheduling); end Draw_Time_Line; procedure my_Redraw_Time_Line (Draw_Scheduling : access Draw_Scheduling_Record) --access Draw_Scheduling_Record'Class) is My_Task_Iterator : Tasks_Iterator; My_Resource_Iterator : Resources_Iterator; My_Buffer_Iterator : Buffers_Iterator; My_Message_Iterator : Messages_Iterator; A_Task : Generic_Task_Ptr; A_Message : Generic_Message_Ptr; A_Resource : Generic_Resource_Ptr; A_Buffer : Buffer_Ptr; I : Gint := 0; Msg, Name : Unbounded_String; type Object_Range is new Integer range 0 .. (Max_Tasks + Max_Resources + Max_Buffers + Max_Messages); Task_Name : array (Object_Range) of Unbounded_String; Resource_Name : array (Object_Range) of Unbounded_String; Message_Name : array (Object_Range) of Unbounded_String; Buffer_Name : array (Object_Range) of Unbounded_String; Task_Id : Gint; Message_Id : Gint; Buffer_Id : Gint; Time_U : Gint; Save_Start_U : array (Object_Range) of Gint := (others => 0); Save_Start_M : array (Object_Range) of Gint := (others => 0); Ok : Boolean; Number_Of_Time_Line : Gint := 0; my_Font : Gdk.Font.Gdk_Font; black_Gc : Gdk.GC.Gdk_GC; begin --------------------------------- -- Clear work space --------------------------------- -- Draw_Scheduling.Buffer := Gtk_Double_Buffer(my_area_1); Draw_Rectangle (--Get_Pixmap (Draw_Scheduling.Buffer), get_window(my_area), Draw_Scheduling.White_Gc, Filled => True, X => 0, Y => 0, Width => Draw_Scheduling.Current_Width, Height => Draw_Scheduling.Current_Height); --------------------------------- -- Draw a line per task --------------------------------- I := 0; reset_iterator (Draw_Scheduling.Tasks, My_Task_Iterator); loop current_element (Draw_Scheduling.Tasks, A_Task, My_Task_Iterator); if To_Display (A_Task.name, Task_Object_Type) then Msg := Lb_Task_Name (Current_Language) & "=" & A_Task.name & " "; case A_Task.task_type is when Aperiodic_Type => Msg := Msg & Lb_Capacity (Current_Language) & To_Unbounded_String ("=") & A_Task.capacity'Img & To_Unbounded_String ("; ") & Lb_Deadline (Current_Language) & To_Unbounded_String ("=") & Aperiodic_Task_Ptr (A_Task).deadline'Img & To_Unbounded_String ("; ") & Lb_Start_Time (Current_Language) & To_Unbounded_String ("=") & A_Task.start_time'Img & To_Unbounded_String ("; ") & Lb_Priority (Current_Language) & To_Unbounded_String ("=") & A_Task.priority'Img & To_Unbounded_String ("; Cpu=") & A_Task.cpu_name; when others => Msg := Msg & Lb_Period (Current_Language) & To_Unbounded_String ("=") & Periodic_Task_Ptr (A_Task).period'Img & To_Unbounded_String ("; ") & Lb_Capacity (Current_Language) & To_Unbounded_String ("=") & A_Task.capacity'Img & To_Unbounded_String ("; ") & Lb_Deadline (Current_Language) & To_Unbounded_String ("=") & Periodic_Task_Ptr (A_Task).deadline'Img & To_Unbounded_String ("; ") & Lb_Start_Time (Current_Language) & To_Unbounded_String ("=") & A_Task.start_time'Img & To_Unbounded_String ("; ") & Lb_Priority (Current_Language) & To_Unbounded_String ("=") & A_Task.priority'Img & To_Unbounded_String ("; Cpu=") & A_Task.cpu_name; end case; if A_Task.task_type = Parametric_Type then Msg := Msg & To_Unbounded_String (";") & Lb_Activation_Rule (Current_Language) & To_Unbounded_String ("=") & Parametric_Task_Ptr (A_Task).activation_rule; end if; -- Draw axis time line if necessary -- -- if (Number_Of_Time_Line mod Gint (Time_Line_Between_Time_Axis)) = -- 0 -- then -- Draw_Time_Line_Axis (Draw_Scheduling, I); -- I := I + 1; -- end if; -- Number_Of_Time_Line := Number_Of_Time_Line + 1; Gdk.GC.Gdk_New (black_Gc, Get_window(my_area)); Gdk.GC.Set_Foreground (black_Gc, Gdk.Color.black (Gtk.Widget.Get_Default_Colormap)); Draw_Text (Get_window(my_area), Draw_Scheduling.Font, Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne + 20, To_String (Msg)); Draw_Line ( Get_window(my_area), Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne, Draw_Scheduling.Left_Margin + Gint (Draw_Scheduling.Period - Draw_Scheduling.Start_Draw) * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne); -- For each line, draw unit time lines -- for J in 0 .. Gint (Draw_Scheduling.Period - Draw_Scheduling.Start_Draw) loop Draw_Line (Get_window(my_area), Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin + J * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne - 3, Draw_Scheduling.Left_Margin + J * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne + 3); end loop; -- Register each task in the name table -- Task_Name (Object_Range (I)) := A_Task.name; I := I + 1; end if; exit when is_last_element (Draw_Scheduling.Tasks, My_Task_Iterator); next_element (Draw_Scheduling.Tasks, My_Task_Iterator); end loop; Gdk.GC.Set_Foreground (Draw_Scheduling.Black_Gc, Gdk.Color.Black (Gtk.Widget.Get_Default_Colormap)); end my_Redraw_Time_Line; procedure Redraw_Time_Line (Draw_Scheduling : access Draw_Scheduling_Record'Class) is My_Task_Iterator : Tasks_Iterator; My_Resource_Iterator : Resources_Iterator; My_Buffer_Iterator : Buffers_Iterator; My_Message_Iterator : Messages_Iterator; A_Task : Generic_Task_Ptr; A_Message : Generic_Message_Ptr; A_Resource : Generic_Resource_Ptr; A_Buffer : Buffer_Ptr; I : Gint := 0; Msg, Name : Unbounded_String; type Object_Range is new Integer range 0 .. (Max_Tasks + Max_Resources + Max_Buffers + Max_Messages); Task_Name : array (Object_Range) of Unbounded_String; Resource_Name : array (Object_Range) of Unbounded_String; Message_Name : array (Object_Range) of Unbounded_String; Buffer_Name : array (Object_Range) of Unbounded_String; Task_Id : Gint; Message_Id : Gint; Buffer_Id : Gint; Time_U : Gint; Save_Start_U : array (Object_Range) of Gint := (others => 0); Save_Start_M : array (Object_Range) of Gint := (others => 0); Ok : Boolean; Number_Of_Time_Line : Gint := 0; begin --------------------------------- -- Clear work space --------------------------------- -- Draw_Scheduling.Buffer := Gtk_Double_Buffer(my_area_1); Draw_Rectangle (get_window(my_area), Draw_Scheduling.White_Gc, Filled => True, X => 0, Y => 0, Width => Draw_Scheduling.Current_Width, Height => Draw_Scheduling.Current_Height); --------------------------------- -- Draw a line per task --------------------------------- I := 0; reset_iterator (Draw_Scheduling.Tasks, My_Task_Iterator); loop current_element (Draw_Scheduling.Tasks, A_Task, My_Task_Iterator); if To_Display (A_Task.name, Task_Object_Type) then Msg := Lb_Task_Name (Current_Language) & "=" & A_Task.name & " "; case A_Task.task_type is when Aperiodic_Type => Msg := Msg & Lb_Capacity (Current_Language) & To_Unbounded_String ("=") & A_Task.capacity'Img & To_Unbounded_String ("; ") & Lb_Deadline (Current_Language) & To_Unbounded_String ("=") & Aperiodic_Task_Ptr (A_Task).deadline'Img & To_Unbounded_String ("; ") & Lb_Start_Time (Current_Language) & To_Unbounded_String ("=") & A_Task.start_time'Img & To_Unbounded_String ("; ") & Lb_Priority (Current_Language) & To_Unbounded_String ("=") & A_Task.priority'Img & To_Unbounded_String ("; Cpu=") & A_Task.cpu_name; when others => Msg := Msg & Lb_Period (Current_Language) & To_Unbounded_String ("=") & Periodic_Task_Ptr (A_Task).period'Img & To_Unbounded_String ("; ") & Lb_Capacity (Current_Language) & To_Unbounded_String ("=") & A_Task.capacity'Img & To_Unbounded_String ("; ") & Lb_Deadline (Current_Language) & To_Unbounded_String ("=") & Periodic_Task_Ptr (A_Task).deadline'Img & To_Unbounded_String ("; ") & Lb_Start_Time (Current_Language) & To_Unbounded_String ("=") & A_Task.start_time'Img & To_Unbounded_String ("; ") & Lb_Priority (Current_Language) & To_Unbounded_String ("=") & A_Task.priority'Img & To_Unbounded_String ("; Cpu=") & A_Task.cpu_name; end case; if A_Task.task_type = Parametric_Type then Msg := Msg & To_Unbounded_String (";") & Lb_Activation_Rule (Current_Language) & To_Unbounded_String ("=") & Parametric_Task_Ptr (A_Task).activation_rule; end if; -- Draw axis time line if necessary -- if (Number_Of_Time_Line mod Gint (Time_Line_Between_Time_Axis)) = 0 then Draw_Time_Line_Axis (Draw_Scheduling, I); I := I + 1; end if; Number_Of_Time_Line := Number_Of_Time_Line + 1; Draw_Text ( Get_window(my_area), Draw_Scheduling.Font, Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne + 20, To_String (Msg)); Draw_Line ( Get_window(my_area), Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne, Draw_Scheduling.Left_Margin + Gint (Draw_Scheduling.Period - Draw_Scheduling.Start_Draw) * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne); -- For each line, draw unit time lines -- for J in 0 .. Gint (Draw_Scheduling.Period - Draw_Scheduling.Start_Draw) loop Draw_Line (Get_window(my_area), Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin + J * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne - 3, Draw_Scheduling.Left_Margin + J * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne + 3); end loop; -- Register each task in the name table -- Task_Name (Object_Range (I)) := A_Task.name; I := I + 1; end if; exit when is_last_element (Draw_Scheduling.Tasks, My_Task_Iterator); next_element (Draw_Scheduling.Tasks, My_Task_Iterator); end loop; ------------------------------------- -- Draw a line for each resource ------------------------------------- if Schedule_With_Resources then if not is_empty (Draw_Scheduling.Resources) then reset_iterator (Draw_Scheduling.Resources, My_Resource_Iterator); loop current_element (Draw_Scheduling.Resources, A_Resource, My_Resource_Iterator); if To_Display (A_Resource.name, Resource_Object_Type) then Msg := Lb_Resource_Name (Current_Language) & "=" & A_Resource.name & " "; if (A_Resource.protocol = Priority_Ceiling_Protocol) then Msg := Msg & To_Unbounded_String ("Protocol = PCP"); else if (A_Resource.protocol = Priority_Inheritance_Protocol) then Msg := Msg & To_Unbounded_String ("Protocol = PIP"); else if (A_Resource.protocol = Immediate_Priority_Ceiling_Protocol) then Msg := Msg & To_Unbounded_String ("Protocol = IPCP"); else Msg := Msg & To_Unbounded_String ("Protocol = No protocol"); end if; end if; end if; Msg := Msg & To_Unbounded_String ("; Cpu=") & A_Task.cpu_name; -- Draw axis time line if necessary -- if (Number_Of_Time_Line mod Gint (Time_Line_Between_Time_Axis)) = 0 then Draw_Time_Line_Axis (Draw_Scheduling, I); I := I + 1; end if; Number_Of_Time_Line := Number_Of_Time_Line + 1; Draw_Text (Get_window(my_area), Draw_Scheduling.Font, Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne + 20, To_String (Msg)); Draw_Line (Get_window(my_area), Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne, Draw_Scheduling.Left_Margin + Gint (Draw_Scheduling.Period - Draw_Scheduling.Start_Draw) * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne); -- For each line, draw unit time lines -- for J in 0 .. Gint (Draw_Scheduling.Period - Draw_Scheduling.Start_Draw) loop Draw_Line (Get_window(my_area), Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin + J * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne - 3, Draw_Scheduling.Left_Margin + J * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne + 3); end loop; -- Register each resource in the name table -- Resource_Name (Object_Range (I)) := A_Resource.name; I := I + 1; end if; exit when is_last_element (Draw_Scheduling.Resources, My_Resource_Iterator); next_element (Draw_Scheduling.Resources, My_Resource_Iterator); end loop; end if; end if; ------------------------------------- -- Draw a line for each message and buffer ------------------------------------- if Schedule_With_Precedencies then if not is_empty (Draw_Scheduling.Messages) then reset_iterator (Draw_Scheduling.Messages, My_Message_Iterator); loop current_element (Draw_Scheduling.Messages, A_Message, My_Message_Iterator); if To_Display (A_Message.name, Message_Object_Type) then Msg := Lb_Message_Name (Current_Language) & "=" & A_Message.name & " "; if A_Message.message_type = Periodic_Type then Msg := Msg & To_Unbounded_String ("Pe=") & Periodic_Message_Ptr (A_Message).period'Img; else Msg := Msg & To_Unbounded_String (" ;Pe= 0"); end if; Msg := Msg & To_Unbounded_String (" ; Delay=") & A_Message.response_time'Img; Msg := Msg & To_Unbounded_String (" ; Size = ") & A_Message.size'Img; -- Draw axis time line if necessary -- if (Number_Of_Time_Line mod Gint (Time_Line_Between_Time_Axis)) = 0 then Draw_Time_Line_Axis (Draw_Scheduling, I); I := I + 1; end if; Number_Of_Time_Line := Number_Of_Time_Line + 1; Draw_Text (Get_window(my_area), Draw_Scheduling.Font, Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne + 20, To_String (Msg)); Draw_Line (Get_window(my_area), Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne, Draw_Scheduling.Left_Margin + Gint (Draw_Scheduling.Period - Draw_Scheduling.Start_Draw) * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne); -- For each line, draw unit time lines -- for J in 0 .. Gint (Draw_Scheduling.Period - Draw_Scheduling.Start_Draw) loop Draw_Line (Get_window(my_area), Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin + J * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne - 3, Draw_Scheduling.Left_Margin + J * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne + 3); end loop; -- Register each message in the name table -- Message_Name (Object_Range (I)) := A_Message.name; I := I + 1; end if; exit when is_last_element (Draw_Scheduling.Messages, My_Message_Iterator); next_element (Draw_Scheduling.Messages, My_Message_Iterator); end loop; end if; if not is_empty (Draw_Scheduling.Buffers) then reset_iterator (Draw_Scheduling.Buffers, My_Buffer_Iterator); loop current_element (Draw_Scheduling.Buffers, A_Buffer, My_Buffer_Iterator); if To_Display (A_Buffer.name, Buffer_Object_Type) then Msg := Lb_Buffer_Name (Current_Language) & "=" & A_Buffer.name & " "; Msg := Msg & To_Unbounded_String ("Size = ") & A_Buffer.size'Img; Msg := Msg & To_Unbounded_String (" ; Cpu = ") & A_Buffer.cpu_name; -- Draw axis time line if necessary -- if (Number_Of_Time_Line mod Gint (Time_Line_Between_Time_Axis)) = 0 then Draw_Time_Line_Axis (Draw_Scheduling, I); I := I + 1; end if; Number_Of_Time_Line := Number_Of_Time_Line + 1; Draw_Text (Get_window(my_area), Draw_Scheduling.Font, Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne + 20, To_String (Msg)); Draw_Line (Get_window(my_area), Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne, Draw_Scheduling.Left_Margin + Gint (Draw_Scheduling.Period - Draw_Scheduling.Start_Draw) * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne); -- For each line, draw unit time lines -- for J in 0 .. Gint (Draw_Scheduling.Period - Draw_Scheduling.Start_Draw) loop Draw_Line (Get_window(my_area), Draw_Scheduling.Black_Gc, Draw_Scheduling.Left_Margin + J * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne - 3, Draw_Scheduling.Left_Margin + J * Draw_Scheduling.Timeunit_Margin, Draw_Scheduling.High_Margin + I * Draw_Scheduling.Interligne + 3); end loop; -- Register each buffer in the name table -- Buffer_Name (Object_Range (I)) := A_Buffer.name; I := I + 1; end if; exit when is_last_element (Draw_Scheduling.Buffers, My_Buffer_Iterator); next_element (Draw_Scheduling.Buffers, My_Buffer_Iterator); end loop; end if; end if; ------------------------------------------ -- Draw information from scheduling table ------------------------------------------ for U in 0 .. Draw_Scheduling.Sched.nb_entries - 1 loop -- processors if Draw_Scheduling.Sched.entries (U).data.error_msg = empty_string then -- Scan scheduling sequence, but only for period-start-draw units --of times -- for K in 0 .. Draw_Scheduling.Sched.entries (U).data.result.nb_entries - 1 loop if (Draw_Scheduling.Sched.entries (U).data.result.entries (K). item >= Draw_Scheduling.Start_Draw) and (Draw_Scheduling.Sched.entries (U).data.result.entries (K). item <= Draw_Scheduling.Period) then case Draw_Scheduling.Sched.entries (U).data.result.entries (K). data.discriminant is ---------------------------------------- -- Draw task running time in black -- (time when the task owns the processor) ---------------------------------------- when Running_Task => Name := Draw_Scheduling.Sched.entries (U).data.result.entries ( K).data.running_task.name; if To_Display (Name, Task_Object_Type) then Ok := False; for L in Object_Range loop if (Task_Name (L) = Name) then Ok := True; Task_Id := Gint (L); Time_U := Gint ( Draw_Scheduling.Sched.entries (U).data.result. entries (K).item - Draw_Scheduling.Start_Draw); end if; end loop; if not Ok then raise Task_Not_Found; end if; Gdk.GC.Set_Foreground (Draw_Scheduling.Black_Gc, Gdk.Color.Black (Gtk.Widget.Get_Default_Colormap)); Draw_Rectangle (Get_window(my_area), Draw_Scheduling.Black_Gc, True, Draw_Scheduling.Timeunit_Margin * Time_U + Draw_Scheduling.Left_Margin, Task_Id * Draw_Scheduling.Interligne + Draw_Scheduling.High_Margin - 3, Draw_Scheduling.Timeunit_Margin, 7); end if; ---------------------------------------- -- Draw task running time in black -- (time when the task owns the processor) ---------------------------------------- when Context_Switch_Overhead => Name := Draw_Scheduling.Sched.entries (U).data.result.entries ( K).data.switched_task.name; if To_Display (Name, Task_Object_Type) then Ok := False; for L in Object_Range loop if (Task_Name (L) = Name) then Ok := True; Task_Id := Gint (L); Time_U := Gint ( Draw_Scheduling.Sched.entries (U).data.result. entries (K).item - Draw_Scheduling.Start_Draw); end if; end loop; if not Ok then raise Task_Not_Found; end if; Gdk.GC.Set_Foreground (Draw_Scheduling.Black_Gc, Draw_Scheduling.Red_Color); Draw_Rectangle (Get_window(my_area), Draw_Scheduling.Black_Gc, True, Draw_Scheduling.Timeunit_Margin * Time_U + Draw_Scheduling.Left_Margin, Task_Id * Draw_Scheduling.Interligne + Draw_Scheduling.High_Margin - 3, Draw_Scheduling.Timeunit_Margin, 7); end if; ----------------------------------------------------- -- Draw each task wake up time in red ----------------------------------------------------- when Task_activation => Name := Draw_Scheduling.Sched.entries (U).data.result.entries ( K).data.activation_task.name; if To_Display (Name, Task_Object_Type) then Ok := False; for L in Object_Range loop if (Task_Name (L) = Name) then Ok := True; Task_Id := Gint (L); Time_U := Gint ( Draw_Scheduling.Sched.entries (U).data.result. entries (K).item - Draw_Scheduling.Start_Draw); end if; end loop; if not Ok then raise Task_Not_Found; end if; Gdk.GC.Set_Foreground (Draw_Scheduling.Black_Gc, Draw_Scheduling.Red_Color); Draw_Rectangle (Get_window(my_area), Draw_Scheduling.Black_Gc, True, Draw_Scheduling.Left_Margin + Draw_Scheduling.Timeunit_Margin * Time_U, Draw_Scheduling.High_Margin + Task_Id * Draw_Scheduling.Interligne - 8, 3, 16); end if; ----------------------------------------------------- -- Draw shared resource allocation in blue color ----------------------------------------------------- when Allocate_Resource => Name := Draw_Scheduling.Sched.entries (U).data.result.entries ( K).data.allocate_resource.name; if To_Display (Name, Resource_Object_Type) then Ok := False; for L in Object_Range loop if (Resource_Name (L) = Name) then Ok := True; Task_Id := Gint (L); Time_U := Gint ( Draw_Scheduling.Sched.entries (U).data.result. entries (K).item - Draw_Scheduling.Start_Draw); end if; end loop; if not Ok then raise Resource_Not_Found; end if; Gdk.GC.Set_Foreground (Draw_Scheduling.Black_Gc, Draw_Scheduling.Blue_Color); Draw_Rectangle (Get_window(my_area), Draw_Scheduling.Black_Gc, True, Draw_Scheduling.Left_Margin + Draw_Scheduling.Timeunit_Margin * Time_U, Draw_Scheduling.High_Margin + Task_Id * Draw_Scheduling.Interligne - 8, 3, 16); Save_Start_U (Object_Range (Task_Id)) := Draw_Scheduling.Left_Margin + Draw_Scheduling.Timeunit_Margin * Time_U; end if; ---------------------------------------- -- Draw shared resource releasing in black ---------------------------------------- when Release_Resource => Name := Draw_Scheduling.Sched.entries (U).data.result.entries ( K).data.release_resource.name; if To_Display (Name, Resource_Object_Type) then Ok := False; for L in Object_Range loop if (Resource_Name (L) = Name) then Ok := True; Task_Id := Gint (L); Time_U := Gint ( Draw_Scheduling.Sched.entries (U).data.result. entries (K).item - Draw_Scheduling.Start_Draw) + 1; end if; end loop; if not Ok then raise Task_Not_Found; end if; Gdk.GC.Set_Foreground (Draw_Scheduling.Black_Gc, Gdk.Color.Black (Gtk.Widget.Get_Default_Colormap)); Draw_Rectangle (Get_window(my_area), Draw_Scheduling.Black_Gc, True, Save_Start_U (Object_Range (Task_Id)), Task_Id * Draw_Scheduling.Interligne + Draw_Scheduling.High_Margin - 3, Draw_Scheduling.Left_Margin + Draw_Scheduling.Timeunit_Margin * Time_U - Save_Start_U (Object_Range (Task_Id)), 7); end if; ---------------------------------------------------- -- Event about buffers -- Draw in red buffer write and in blue buffer read ---------------------------------------------------- when Write_To_Buffer => Name := Draw_Scheduling.Sched.entries (U).data.result.entries ( K).data.write_buffer.name; if To_Display (Name, Buffer_Object_Type) then Ok := False; for L in Object_Range loop if (Buffer_Name (L) = Name) then Ok := True; Buffer_Id := Gint (L); Time_U := Gint ( Draw_Scheduling.Sched.entries (U).data.result. entries (K).item); end if; end loop; if not Ok then raise Buffer_Not_Found; end if; Gdk.GC.Set_Foreground (Draw_Scheduling.Black_Gc, Draw_Scheduling.Blue_Color); Draw_Rectangle (Get_window(my_area), Draw_Scheduling.Black_Gc, True, Draw_Scheduling.Timeunit_Margin * Time_U + Draw_Scheduling.Left_Margin, Buffer_Id * Draw_Scheduling.Interligne + Draw_Scheduling.High_Margin - 3, Draw_Scheduling.Timeunit_Margin, 7); end if; when Read_From_Buffer => Name := Draw_Scheduling.Sched.entries (U).data.result.entries ( K).data.read_buffer.name; if To_Display (Name, Buffer_Object_Type) then Ok := False; for L in Object_Range loop if (Buffer_Name (L) = Name) then Ok := True; Buffer_Id := Gint (L); Time_U := Gint ( Draw_Scheduling.Sched.entries (U).data.result. entries (K).item - Draw_Scheduling.Start_Draw); end if; end loop; if not Ok then raise Buffer_Not_Found; end if; Gdk.GC.Set_Foreground (Draw_Scheduling.Black_Gc, Draw_Scheduling.Red_Color); Draw_Rectangle (Get_window(my_area), Draw_Scheduling.Black_Gc, True, Draw_Scheduling.Timeunit_Margin * Time_U + Draw_Scheduling.Left_Margin, Buffer_Id * Draw_Scheduling.Interligne + Draw_Scheduling.High_Margin - 3, Draw_Scheduling.Timeunit_Margin, 7); end if; ---------------------------------------- -- Event about messages -- Draw in red message communication time ---------------------------------------- when Send_Message => Name := Draw_Scheduling.Sched.entries (U).data.result.entries ( K).data.send_message.name; if To_Display (Name, Message_Object_Type) then Ok := False; for L in Object_Range loop if (Message_Name (L) = Name) then Ok := True; Message_Id := Gint (L); Time_U := Gint ( Draw_Scheduling.Sched.entries (U).data.result. entries (K).item); end if; end loop; if not Ok then raise Message_Not_Found; end if; -- Save the time the message is sent -- Save_Start_M (Object_Range (Message_Id)) := Time_U; end if; when Receive_Message => Name := Draw_Scheduling.Sched.entries (U).data.result.entries ( K).data.receive_message.name; if To_Display (Name, Message_Object_Type) then Ok := False; for L in Object_Range loop if (Message_Name (L) = Name) then Ok := True; Message_Id := Gint (L); Time_U := Gint ( Draw_Scheduling.Sched.entries (U).data.result. entries (K).item - Draw_Scheduling.Start_Draw); end if; end loop; if not Ok then raise Message_Not_Found; end if; Gdk.GC.Set_Foreground (Draw_Scheduling.Black_Gc, Draw_Scheduling.Red_Color); Draw_Rectangle (Get_window(my_area), Draw_Scheduling.Black_Gc, True, Draw_Scheduling.Left_Margin + Save_Start_M (Object_Range (Message_Id)) * Draw_Scheduling.Timeunit_Margin, Message_Id * Draw_Scheduling.Interligne + Draw_Scheduling.High_Margin - 3, Draw_Scheduling.Timeunit_Margin * (Time_U - Save_Start_M (Object_Range (Message_Id))), 7); end if; ------------------------------------------- -- Events we have nothing to display ------------------------------------------- when others => null; end case; end if; end loop; end if; end loop; Gdk.GC.Set_Foreground (Draw_Scheduling.Black_Gc, Gdk.Color.Black (Gtk.Widget.Get_Default_Colormap)); --------------------- -- Flush data in the window --------------------- --utiliser ceci quand je passe par configure ...... --Draw (Draw_Scheduling.Buffer); end Redraw_Time_Line; end graphical_editor.Draw_Scheduling_Pkg;