|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: B T
Length: 54218 (0xd3ca)
Types: TextFile
Names: »B«
└─⟦85b835f43⟧ Bits:30000549 8mm tape, Rational 1000, Xlib rev 6.00
└─⟦0c20f784e⟧ »DATA«
└─⟦1abbe589f⟧
└─⟦059497ac5⟧
└─⟦this⟧
--/ if R1000 then
with Transport;
with Transport_Defs;
with Transport_Name;
--/ elsif Cdf_Hpux then
--// with C_Library_Interface;
--// with System_Interface;
--// with Unix_Base_Types;
--/ elsif TeleGen2 and then Unix then
--// with Error_Messages; -- Unix errors
--/ end if;
with Xlbt_Arithmetic;
use Xlbt_Arithmetic;
with Xlbt_Basic;
use Xlbt_Basic;
with Xlbt_Display2;
use Xlbt_Display2;
with Xlbt_Error;
use Xlbt_Error;
with Xlbt_Event;
use Xlbt_Event;
with Xlbt_Event3;
with Xlbt_Exceptions;
use Xlbt_Exceptions;
with Xlbt_Proc_Var;
use Xlbt_Proc_Var;
with Xlbt_Request;
use Xlbt_Request;
with Xlbp_Error;
use Xlbp_Error;
with Xlbp_Proc_Var;
use Xlbp_Proc_Var;
with Xlbit_Library3;
use Xlbit_Library3;
with Xlbip_Internal;
use Xlbip_Internal;
with Xlbip_Wire_Converters;
use Xlbip_Wire_Converters;
with Xlbmt_Network_Types;
use Xlbmt_Network_Types;
with Xlbmt_Transport_Defs;
use Xlbmt_Transport_Defs;
with Xlbmp_Environment;
use Xlbmp_Environment;
with Xlbmp_Network_Interface;
use Xlbmp_Network_Interface;
with Xlbit_Library2; -- This is here to cause the linking and the
-- elaboration of the body of this package.
with Xlbmp_Debugger; -- This is here to cause the linking and the
-- elaboration of the body of this package.
pragma Elaborate (Xlbmp_Debugger);
package body Xlbmp_Internal is
------------------------------------------------------------------------------
-- X Library Machine Dependent Internal Support
--
-- Xlbmp_Internal - Very low-level routines for internal X Library support
------------------------------------------------------------------------------
-- Copyright 1989 - 1991 by Rational, Santa Clara, California.
-- Copyright 1985 - 1989 by the Massachusetts Institute of Technology
--
-- All Rights Reserved.
--
-- Permission to use, copy, modify, and distribute this software and its
-- documentation for any purpose and without fee is hereby granted,
-- provided that the above copyright notice(s) appear in all copies and that
-- both that copyright notice(s) and this permission notice appear in
-- supporting documentation, and that the names of MIT or Rational not be
-- used in advertising or publicity pertaining to distribution of the software
-- without specific, written prior permission.
--
-- MIT and Rational disclaim all warranties with regard to this software,
-- including all implied warranties of merchantability and fitness, in no
-- event shall MIT or Rational be liable for any special, indirect or
-- consequential damages or any damages whatsoever resulting from loss of use,
-- data or profits, whether in an action of contract, negligence or other
-- tortious action, arising out of or in connection with the use or performance
-- of this software.
------------------------------------------------------------------------------
--\f
--/ if R1000 then
function "=" (A, B : Transport_Defs.Network_Name) return Boolean
renames Transport_Defs."=";
--/ end if;
X_Tcp_Port : constant := 6000; -- add display number to this
-- Base X server socket/port number
Unexp_Reply : constant X_String :=
"Reply_Event received when not expected. Out of sync?";
Unknown_Host : constant X_String := "Host name (or number) is unknown:";
------------------------------------------------------------------------------
-- Length of any Event/Error that we can receive from the X server. They are
-- all the same size.
------------------------------------------------------------------------------
Event_Length : constant X_Raw_Data_Index :=
Xlbt_Event3.X_Button_Event'Size / 8;
--\f
function Internal_X_Events_Queued (Display : X_Display;
Mode : X_Event_Queuing) return S_Long is
------------------------------------------------------------------------------
-- Read in any pending events and return the number of queued events.
------------------------------------------------------------------------------
Rec_Next : X_Raw_Data_Index := 1;
Rec_Len : X_Raw_Data_Index := 0;
New_Next_M1 : X_Raw_Data_Index;
Client_Sent : Boolean;
Code : X_Event_Code;
Er : X_Error_Contents;
Ev : X_Event;
Queue_It : X_Status;
begin
----If requested then we will flush first.
if Mode = Queued_After_Flush then
Internal_X_Flush_Display (Display);
if Display.Q_Len > 0 then
return Display.Q_Len;
end if;
end if;
----If we have gotten an I/O error then don't do more I/O.
if Display.Flags (Xlib_Display_Io_Error) then
return 0;
end if;
----If there is any pending input in Display.Input then put that into our buffer
-- and add new information to it.
if Display.Input.Used < Display.Input.Data'Last then
Receive_Maybe
(Display.Network.Fd,
Display.Network.Fd_Error,
Display.Input.Data
(Display.Input.Used + 1 .. Display.Input.Data'Last),
Rec_Len);
Display.Input.Used := Display.Input.Used + Rec_Len;
----See if our Receive had an error. Timed_Out is fine; return if there's no
-- data to be had.
if Display.Network.Fd_Error /= Ok and then
Display.Network.Fd_Error /= Timed_Out then
Report_Io_Error (Display, "Receive");
end if;
if Display.Input.Used = 0 then
return Display.Q_Len;
end if;
end if;
----Loop until we've used up all of the data in the buffer.
while Rec_Next <= Display.Input.Used loop
----We assume here that all Event/Error packets are the same size. This is
-- currently true. X11.V1 1/6/88. Calculate the end of the record.
New_Next_M1 := Rec_Next + Event_Length - 1;
----If there isn't enough data in the buffer to make up the next record then
-- we'll read in some more data. We watch carefully to make sure that we
-- don't overflow the buffer.
if New_Next_M1 > Display.Input.Used then
if New_Next_M1 > Display.Input.Data'Last then
New_Next_M1 := Display.Input.Used;
Display.Input.Used := Display.Input.Used - Rec_Next + 1;
Display.Input.Data (1 .. Display.Input.Used) :=
Display.Input.Data (Rec_Next .. New_Next_M1);
Rec_Next := 1;
New_Next_M1 := Rec_Next + Event_Length - 1;
end if;
Receive_Maybe
(Display.Network.Fd,
Display.Network.Fd_Error,
Display.Input.Data
(Display.Input.Used + 1 .. Display.Input.Data'Last),
Rec_Len);
Display.Input.Used := Display.Input.Used + Rec_Len;
----If we timed out and/or there still isn't enough data to process then save
-- the pending data in Display.Input and return. Check for errors as well.
if Display.Network.Fd_Error /= Ok and then
Display.Network.Fd_Error /= Timed_Out then
Report_Io_Error (Display, "Receive");
end if;
if New_Next_M1 > Display.Input.Used then
if Rec_Next > 1 then
New_Next_M1 := Display.Input.Used;
Display.Input.Used := Display.Input.Used - Rec_Next + 1;
Display.Input.Data (1 .. Display.Input.Used) :=
Display.Input.Data (Rec_Next .. New_Next_M1);
end if;
return Display.Q_Len;
end if;
end if;
----Take the next record and convert it appropriately.
--/ if Raw_Is_Unsigned then
if Display.Input.Data (Rec_Next) > 127 then
Client_Sent := True;
Code := X_Event_Code'Val (Display.Input.Data (Rec_Next) - 128);
else
Client_Sent := False;
Code := X_Event_Code'Val (Display.Input.Data (Rec_Next));
end if;
--/ else
--// if Display.Input.Data (Rec_Next) < 0 then
--// Client_Sent := True;
--// Code := X_Event_Code'Val
--// ((Display.Input.Data (Rec_Next) + 127) + 1);
--// else
--// Client_Sent := False;
--// Code := X_Event_Code'Val (Display.Input.Data (Rec_Next));
--// end if;
--/ end if;
Display.Input.Data (Rec_Next) := X_Event_Code'Pos (Code);
case Code is
----Error are converted and immediately reported.
when Error_Event =>
Internal_Wire_To_Error
(Display,
Display.Input.Data (Rec_Next .. New_Next_M1),
Client_Sent,
Er);
declare
Proc : X_Procedure_Variable;
begin
X_Lib.Get_Error (Display, Proc);
Proc_Var_X_Error_Function.Call
(Proc_Var_X_Error_Function.To_Pv (Proc),
Display, Er);
end;
----Replies should not happen here.
when Reply_Event =>
----This isn't supposed to happen. Replies are always
-- waited for; something is very wrong.
declare
Proc : X_Procedure_Variable;
begin
X_Lib.Get_Io_Error (Display, Proc);
Err (Display.Last_Error,
X_Get_Error_String ("XlibError", "UnexpReply",
Unexp_Reply));
Proc_Var_X_Io_Error_Function.Call
(Proc_Var_X_Io_Error_Function.To_Pv (Proc), Display);
raise X_Network_Io_Error;
end;
----Everything else is assumed to be an Event.
when others =>
Proc_Var_X_Wire_Event.Call
(Proc_Var_X_Wire_Event.To_Pv (Display.Event_Vec (Code)),
Display,
Display.Input.Data (Rec_Next .. New_Next_M1),
Client_Sent,
Ev,
Queue_It);
if Queue_It = Successful then
Internal_X_Enq (Display, Ev);
end if;
end case;
Rec_Next := New_Next_M1 + 1;
end loop;
----Can't read any more; return the present queue length.
Display.Input.Used := 0; -- Reset to zero since it's all used up.
return Display.Q_Len;
end Internal_X_Events_Queued;
--\f
procedure Internal_X_Wait_For_Writable (Display : X_Display) is
------------------------------------------------------------------------------
-- This is an OS dependent routine which:
-- 1) returns as soon as the connection can be written on....
-- 2) if the connection can be read, must enqueue events and handle errors,
-- until the connection is writable.
-- NOTE: On the R1000 we cannot do this since there is no way to test for
-- "writability"; silly machine; what we do instead is read anything that is
-- available and return when we've used up everything that we can readily get.
------------------------------------------------------------------------------
Rec_Next : X_Raw_Data_Index := 1;
Rec_Len : X_Raw_Data_Index := 0;
New_Next_M1 : X_Raw_Data_Index;
Client_Sent : Boolean;
Code : X_Event_Code;
Er : X_Error_Contents;
Ev : X_Event;
Queue_It : X_Status;
Did_Something : Boolean := False;
begin
----If there is any pending input in Display.Input then put that into our buffer
-- and add new information to it.
if Display.Input.Used < Display.Input.Data'Last then
Receive_Maybe
(Display.Network.Fd,
Display.Network.Fd_Error,
Display.Input.Data
(Display.Input.Used + 1 .. Display.Input.Data'Last),
Rec_Len);
Display.Input.Used := Display.Input.Used + Rec_Len;
----See if our Receive had an error. Timed_Out is fine; return if there's no
-- data to be had.
if Display.Network.Fd_Error /= Ok and then
Display.Network.Fd_Error /= Timed_Out then
Report_Io_Error (Display, "Receive");
end if;
if Display.Input.Used = 0 then
Did_Something := Rec_Len > 0;
goto All_Done;
end if;
end if;
----Loop until we've used up all of the data in the buffer.
while Rec_Next <= Display.Input.Used loop
----We assume here that all Event/Error packets are the same size. This is
-- currently true. X11.V1 1/6/88. Calculate the end of the record.
New_Next_M1 := Rec_Next + Event_Length - 1;
----If there isn't enough data in the buffer to make up the next record then
-- we'll read in some more data. We watch carefully to make sure that we
-- don't overflow the buffer.
if New_Next_M1 > Display.Input.Used then
if New_Next_M1 > Display.Input.Data'Last then
New_Next_M1 := Display.Input.Used;
Display.Input.Used := Display.Input.Used - Rec_Next + 1;
Display.Input.Data (1 .. Display.Input.Used) :=
Display.Input.Data (Rec_Next .. New_Next_M1);
Rec_Next := 1;
New_Next_M1 := Event_Length;
end if;
Receive_Maybe
(Display.Network.Fd,
Display.Network.Fd_Error,
Display.Input.Data
(Display.Input.Used + 1 .. Display.Input.Data'Last),
Rec_Len);
Display.Input.Used := Display.Input.Used + Rec_Len;
----If we timed out and/or there still isn't enough data to process then save
-- the pending data in Display.Input and return. Check for errors as well.
if Display.Network.Fd_Error /= Ok and then
Display.Network.Fd_Error /= Timed_Out then
Report_Io_Error (Display, "Receive");
end if;
if New_Next_M1 > Display.Input.Used then
if Rec_Next > 1 then
New_Next_M1 := Display.Input.Used;
Display.Input.Used := Display.Input.Used - Rec_Next + 1;
Display.Input.Data (1 .. Display.Input.Used) :=
Display.Input.Data (Rec_Next .. New_Next_M1);
end if;
Did_Something := Did_Something or Rec_Len > 0;
goto All_Done;
end if;
end if;
----Take the next record and convert it appropriately.
--/ if Raw_Is_Unsigned then
if Display.Input.Data (Rec_Next) > 127 then
Client_Sent := True;
Code := X_Event_Code'Val (Display.Input.Data (Rec_Next) - 128);
else
Client_Sent := False;
Code := X_Event_Code'Val (Display.Input.Data (Rec_Next));
end if;
--/ else
--// if Display.Input.Data (Rec_Next) < 0 then
--// Client_Sent := True;
--// Code := X_Event_Code'Val
--// ((Display.Input.Data (Rec_Next) + 127) + 1);
--// else
--// Client_Sent := False;
--// Code := X_Event_Code'Val (Display.Input.Data (Rec_Next));
--// end if;
--/ end if;
Display.Input.Data (Rec_Next) := X_Event_Code'Pos (Code);
Did_Something := True;
case Code is
----Error are converted and immediately reported.
when Error_Event =>
Internal_Wire_To_Error
(Display,
Display.Input.Data (Rec_Next .. New_Next_M1),
Client_Sent,
Er);
declare
Proc : X_Procedure_Variable;
begin
X_Lib.Get_Error (Display, Proc);
Proc_Var_X_Error_Function.Call
(Proc_Var_X_Error_Function.To_Pv (Proc),
Display, Er);
end;
----Replies should not happen here.
when Reply_Event =>
----This isn't supposed to happen. Replies are always
-- waited for; something is very wrong.
declare
Proc : X_Procedure_Variable;
begin
X_Lib.Get_Io_Error (Display, Proc);
Err (Display.Last_Error,
X_Get_Error_String ("XlibError", "UnexpReply",
Unexp_Reply));
Proc_Var_X_Io_Error_Function.Call
(Proc_Var_X_Io_Error_Function.To_Pv (Proc),
Display);
raise X_Network_Io_Error;
end;
----Everything else is assumed to be an Event.
when others =>
Proc_Var_X_Wire_Event.Call
(Proc_Var_X_Wire_Event.To_Pv (Display.Event_Vec (Code)),
Display,
Display.Input.Data (Rec_Next .. New_Next_M1),
Client_Sent,
Ev,
Queue_It);
if Queue_It = Successful then
Internal_X_Enq (Display, Ev);
end if;
end case;
Rec_Next := New_Next_M1 + 1;
end loop;
Display.Input.Used := 0; -- Reset to zero since data all used up.
----Come here when we are ready to return to our caller. If we didn't really
-- do anything then we delay for a while so we aren't a busy-loop chewing up
-- the entire cpu. (If some OS has an option to this then we do that.)
<<All_Done>> null;
--/ if R1000 then
if not Did_Something then
delay 0.25;
end if;
--/ elsif TeleGen2 and then Unix then
--// declare
--// Void : S_Long;
--// Fdset : S_Long := 2 ** Natural(Display.Network.Fd);
--// Timer : Timeval := (Tv_Sec => 1, Tv_Usec => 0);
--// begin
--// Void := Unix_Select (S_Long(Display.Network.Fd),-- Only the one FD
--// None_System_Address,-- Read is don't care
--// Fdset'Address, -- Check for writable
--// Fdset'Address, -- Check for except's
--// Timer'Address); -- Wait for 1 second
--// end;
--/ else
--// if not Did_Something then
--// delay 0.5;
--// end if;
--/ end if;
end Internal_X_Wait_For_Writable;
--\f
procedure Internal_X_Flush_Display (Display : X_Display) is
------------------------------------------------------------------------------
-- Flush the X request buffer. If the buffer is empty, no action is taken.
-- If the entire write cannot be done without blocking then do partial writes
-- and read Error/Events in between.
------------------------------------------------------------------------------
Amount : X_Raw_Data_Index;
Start : X_Raw_Data_Index := 1;
Finish : X_Raw_Data_Index;
begin
----If we have gotten an I/O error then don't do more I/O.
if Display.Flags (Xlib_Display_Io_Error) then
return;
end if;
----If there is a Last_Req that isn't in the output buffer yet then put it
-- there. We know that it will fit in the remaining room.
if Display.Last_Request.Kind /= Invalid_Request then
Internal_X_Flush_Last_Request (Display);
end if;
----Don't transmit zero data.
Finish := Display.Output.Used;
if Finish = 0 then
return;
end if;
----Debug Printout
-- Put ("Internal_X_Flush_Display");
-- Put (S_Long (Finish));
-- Put_Line (" bytes.");
-- for I in Start .. Finish loop
-- declare
-- use Text_Io;
-- use S_Long_Io;
-- D1, D2 : X_Raw_Data_Index;
-- begin
-- D1 := X_Raw_Data_Index (Display.Output.Data (I)) / 16;
-- D2 := X_Raw_Data_Index (Display.Output.Data (I)) rem 16;
-- Put (' ');
-- if D1 < 10 then
-- Put (Character'Val (Character'Pos ('0') + D1));
-- else
-- Put (Character'Val (Character'Pos ('a') - 10 + D1));
-- end if;
-- if D2 < 10 then
-- Put (Character'Val (Character'Pos ('0') + D2));
-- else
-- Put (Character'Val (Character'Pos ('a') - 10 + D2));
-- end if;
-- end;
-- end loop;
-- New_Line;
----Attempt a write.
loop
Transmit_Maybe (Display.Network.Fd,
Display.Network.Fd_Error,
Display.Output.Data (Start .. Finish),
Amount);
----See if we timed out; if so then read a while and try again.
Start := Start + Amount;
if Start > Finish or else
(Display.Network.Fd_Error /= Timed_Out and then
Display.Network.Fd_Error /= Ok) then
exit;
end if;
Internal_X_Wait_For_Writable (Display);
end loop;
----If the write failed then we call the IO error function; he's not expected to
-- return.
if Display.Network.Fd_Error /= Ok then
Report_Io_Error (Display, "Transmit");
end if;
Display.Output.Used := 0;
end Internal_X_Flush_Display;
--\f
procedure Internal_X_Read_Events (Display : X_Display) is
------------------------------------------------------------------------------
-- Don't return until we read and queue up at least one new event. Just like
-- Internal_X_Events_Queued except that we don't return a count and we don't
-- return until we've read at least one.
------------------------------------------------------------------------------
Rec_Next : X_Raw_Data_Index := 1;
Rec_Len : X_Raw_Data_Index := 0;
New_Next_M1 : X_Raw_Data_Index;
Client_Sent : Boolean;
Code : X_Event_Code;
Er : X_Error_Contents;
Ev : X_Event;
Orig_Q_Len : S_Long := Display.Q_Len;
Queue_It : X_Status;
Not_Yet_Flushed : Boolean := True;
begin
----If we have gotten an I/O error then don't do more I/O.
if Display.Flags (Xlib_Display_Io_Error) then
return;
end if;
----If there is any pending input in Display.Input then put that into our buffer
-- and add new information to it.
if Display.Input.Used < Display.Input.Data'Last then
Receive_Maybe
(Display.Network.Fd,
Display.Network.Fd_Error,
Display.Input.Data
(Display.Input.Used + 1 .. Display.Input.Data'Last),
Rec_Len);
Display.Input.Used := Display.Input.Used + Rec_Len;
----See if our Receive had an error. Timed_Out is fine; we'll fix that below.
if Display.Network.Fd_Error /= Ok and then
Display.Network.Fd_Error /= Timed_Out then
Report_Io_Error (Display, "Receive");
end if;
end if;
----Loop until we've used up all of the data in the buffer.
while Display.Q_Len = Orig_Q_Len loop
----We assume here that all Event/Error packets are the same size. This is
-- currently true. X11.V1 1/6/88. Calculate the end of the record.
New_Next_M1 := Rec_Next + Event_Length - 1;
----If there isn't enough data in the buffer to make up the next record then
-- we'll read in some more data. We watch carefully to make sure that we
-- don't overflow the buffer.
if New_Next_M1 > Display.Input.Used then
if New_Next_M1 > Display.Input.Data'Last then
New_Next_M1 := Display.Input.Used;
Display.Input.Used := Display.Input.Used - Rec_Next + 1;
Display.Input.Data (1 .. Display.Input.Used) :=
Display.Input.Data (Rec_Next .. New_Next_M1);
Rec_Next := 1;
New_Next_M1 := Event_Length;
end if;
if Not_Yet_Flushed then
Internal_X_Flush_Display (Display);
if Orig_Q_Len /= Display.Q_Len then
return;
end if;
Not_Yet_Flushed := False;
end if;
Receive_Maybe
(Display.Network.Fd,
Display.Network.Fd_Error,
Display.Input.Data
(Display.Input.Used + 1 .. Display.Input.Data'Last),
Rec_Len);
Display.Input.Used := Display.Input.Used + Rec_Len;
----If we timed out and there still isn't enough data to process then if we have
-- a new event then save the pending data in Display.Input and return;
-- otherwise we wait forever for more data. Check for errors as well.
if Display.Network.Fd_Error /= Ok and then
Display.Network.Fd_Error /= Timed_Out then
Report_Io_Error (Display, "Receive");
end if;
if New_Next_M1 > Display.Input.Used then
if Display.Q_Len > Orig_Q_Len then
if Rec_Next > 1 then
New_Next_M1 := Display.Input.Used;
Display.Input.Used :=
Display.Input.Used - Rec_Next + 1;
Display.Input.Data (1 .. Display.Input.Used) :=
Display.Input.Data (Rec_Next .. New_Next_M1);
end if;
return;
end if;
Receive_Must (Display.Network.Fd,
Display.Network.Fd_Error,
Display.Input.Data
(Display.Input.Used + 1 .. New_Next_M1),
Rec_Len);
Display.Input.Used := Display.Input.Used + Rec_Len;
if Display.Network.Fd_Error /= Ok then
Report_Io_Error (Display, "Receive");
end if;
end if;
end if;
----Take the next record and convert it appropriately.
--/ if Raw_Is_Unsigned then
if Display.Input.Data (Rec_Next) > 127 then
Client_Sent := True;
Code := X_Event_Code'Val (Display.Input.Data (Rec_Next) - 128);
else
Client_Sent := False;
Code := X_Event_Code'Val (Display.Input.Data (Rec_Next));
end if;
--/ else
--// if Display.Input.Data (Rec_Next) < 0 then
--// Client_Sent := True;
--// Code := X_Event_Code'Val
--// ((Display.Input.Data (Rec_Next) + 127) + 1);
--// else
--// Client_Sent := False;
--// Code := X_Event_Code'Val (Display.Input.Data (Rec_Next));
--// end if;
--/ end if;
Display.Input.Data (Rec_Next) := X_Event_Code'Pos (Code);
case Code is
----Errors are converted and immediately reported.
when Error_Event =>
Internal_Wire_To_Error
(Display,
Display.Input.Data (Rec_Next .. New_Next_M1),
Client_Sent,
Er);
declare
Proc : X_Procedure_Variable;
begin
X_Lib.Get_Error (Display, Proc);
Proc_Var_X_Error_Function.Call
(Proc_Var_X_Error_Function.To_Pv (Proc),
Display, Er);
end;
----Replies should not happen here.
when Reply_Event =>
----This isn't supposed to happen. Replies are always
-- waited for; something is very wrong.
declare
Proc : X_Procedure_Variable;
begin
X_Lib.Get_Io_Error (Display, Proc);
Err (Display.Last_Error,
X_Get_Error_String ("XlibError", "UnexpReply",
Unexp_Reply));
Proc_Var_X_Io_Error_Function.Call
(Proc_Var_X_Io_Error_Function.To_Pv (Proc), Display);
raise X_Network_Io_Error;
end;
----Everything else is assumed to be an Event.
when others =>
Proc_Var_X_Wire_Event.Call
(Proc_Var_X_Wire_Event.To_Pv (Display.Event_Vec (Code)),
Display,
Display.Input.Data (Rec_Next .. New_Next_M1),
Client_Sent,
Ev,
Queue_It);
if Queue_It = Successful then
Internal_X_Enq (Display, Ev);
end if;
end case;
Rec_Next := New_Next_M1 + 1;
end loop;
----Can't read any more. Save whatever's left of the Input and return.
if New_Next_M1 = Display.Input.Used then
Display.Input.Used := 0;
else
Rec_Next := Display.Input.Used;
Display.Input.Used := Display.Input.Used - New_Next_M1;
Display.Input.Data (1 .. Display.Input.Used) :=
Display.Input.Data (New_Next_M1 + 1 .. Rec_Next);
end if;
end Internal_X_Read_Events;
--\f
--/ if R1000 then
procedure Make_Host_Connection
(Host : X_String;
Display_Num : U_Char;
Connection : in out Connection_Id;
Host_Addr : out X_Network_Host_Address;
Status : out X_Status;
Error : in out X_Error_String) is
------------------------------------------------------------------------------
-- Given a non-empty host name string and a display number; do the network
-- stuff necessary to locate that host on the network; open a socket to that
-- host; and connect to the proper X server on that host. When we return we
-- have an open network connection that has as-yet transmitted nothing in
-- either direction.
------------------------------------------------------------------------------
--/ if R1000_Xlib_Only then
--// Fd : Connection_Id;
--/ else
Fd : Transport.Connection_Id;
Fd_Conn : Connection_Id;
--/ end if;
Fd_Error : Status_Code;
Socket : S_Natural := X_Tcp_Port + S_Natural (Display_Num);
Host_Address : X_Network_Host_Address;
begin
----Determine what network this host is on and get his host ID.
begin
declare
Network_Id : constant Transport_Defs.Network_Name :=
Transport_Name.Host_To_Network_Name (To_String (Host));
Host_Num : constant Host_Id :=
Transport_Name.Host_To_Host_Id (To_String (Host));
begin
----If he isn't on TCP/IP then we don't currently support him as we don't know
-- how to create his Socket_Id.
if Network_Id /= "TCP/IP" then
Err (Error,
X_Get_Error_String
("XlibError", "OnlyTCPIP",
"Only TCP/IP is currently supported."));
Status := Failed;
return;
end if;
----Open up a socket on his network.
Transport.Open (Fd, Fd_Error, Network_Id);
if Fd_Error /= Ok then
Err (Error, X_Get_Error_String
("XlibError", "TOpenFailed",
"Transport.Open call failed:") &
' ' & To_X_String (Image (Fd_Error)));
Status := Failed;
return;
end if;
----Now try to connect our socket to his socket.
Transport.Connect
(Fd, Fd_Error, Host_Num,
(0 => X_Raw_Data ((Socket / 2 ** 8) rem 2 ** 8),
1 => X_Raw_Data (Socket rem 2 ** 8)));
if Fd_Error /= Ok then
Transport.Close (Fd);
Err (Error, X_Get_Error_String
("XlibError", "TConnectFailed",
"Transport.Connect call failed:") &
' ' & To_X_String (Image (Fd_Error)));
Status := Failed;
return;
end if;
----We made it. Return the open connection.
Host_Address := new Host_Id'(Host_Num);
--/ if R1000_Xlib_Only then
--// Connection := Fd;
--/ else
Fd_Conn := new Connection_Id_Rec;
Fd_Conn.Connection := Fd;
Fd_Conn.Reader.Initialize (Fd_Conn);
Connection := Fd_Conn;
--/ end if;
Host_Addr := Host_Address;
Status := Successful;
return;
end;
exception
when Transport_Name.Undefined =>
Err (Error, X_Get_Error_String ("XlibError", "UndefHost",
"Host is undefined:") &
' ' & Host);
Status := Failed;
return;
when others =>
Free_X_Network_Host_Address (Host_Address);
--/ if R1000_Xlib_Only then
--// Transport.Disconnect (Fd);
--// Transport.Close (Fd);
--/ else
abort Fd_Conn.Reader;
Transport.Disconnect (Fd_Conn.Connection);
Transport.Close (Fd_Conn.Connection);
Free_Connection_Id (Fd_Conn);
--/ end if;
raise;
end;
end Make_Host_Connection;
--/ end if; -- R1000
--\f
--/ if Unix then
--//
--// procedure Make_Host_Connection (Host : X_String;
--// Display_Num : U_Char;
--// Connection : in out Connection_Id;
--// Host_Addr : out X_Network_Host_Address;
--// Status : out X_Status;
--// Error : in out X_Error_String) is
--// ------------------------------------------------------------------------------
--// -- Given a non-empty host name string and a display number; do the network
--// -- stuff necessary to locate that host on the network; open a socket to that
--// -- host; and connect to the proper X server on that host. When we return we
--// -- have an open network connection that has as-yet transmitted nothing in
--// -- either direction.
--// ------------------------------------------------------------------------------
--// Host_Asciz : String (1 .. Host'Length + 1) :=
--// To_String (Host) & Ascii.Nul;
--// Fd : Connection_Id;
--// Void : S_Long;
--// Socket_No : S_Natural := X_Tcp_Port + S_Natural (Display_Num);
--// Host_Num : Host_Id;
--// Hostentptr : Hostent_Pointer;
--// Sock : Sockaddr_In;
--// begin
--//
--// ----Get the host's id number. Host might be a number ("123.4.56.32") or it
--// -- might be a name.
--//
--// if Host (Host'First) in '0' .. '9' then
--// ----Try for a number.
--// Host_Num := Inet_Addr (Host_Asciz (1)'Address);
--// if Host_Num /= -1 then
--// goto Have_Host_Num;
--// end if;
--// end if;
--// ----Try for a name.
--// if Host = "" or else Host = "unix" or else Host = "UNIX" then
--// Make_Host_Connection (Host => X_Env_Get_Host_Name,
--// Display_Num => Display_Num,
--// Connection => Connection,
--// Host_Addr => Host_Addr,
--// Status => Status,
--// Error => Error);
--// return;
--//
--// end if;
--// Hostentptr := Get_Host_By_Name (Host_Asciz (1)'Address);
--// if Hostentptr = null then
--// Err (Error, X_Get_Error_String
--// ("XlibError", "UnknownHost", Unknown_Host) &
--// ' ' & Host);
--// Status := Failed;
--// return;
--// end if;
--// Host_Num := Hostentptr.H_Addr_List.all.A;
--// <<Have_Host_Num>> null;
--//
--// ----Finish creating the socket description information.
--//
--// Sock.Sin_Family := S_Short (Hostentptr.H_Addrtype);
--// Sock.Sin_Port := U_Short (Socket_No);
--// Sock.Sin_Addr.S_Addr := Host_Num;
--// Sock.Sin_Zero := (others => 0);
--//
--// ----Obtain a socket to use.
--//
--// Fd := Socket (S_Long (Sock.Sin_Family), Sock_Stream, 0);
--// if Fd < 0 then
--// Err (Error, X_Get_Error_String ("XlibError", "CannotSocket",
--// "Cannot allocate network socket:") &
--// ' ' & To_X_String
--/ if Cdf_Hpux then
--// (Unix_Base_Types.To_String
--// (C_Library_Interface.Error.Strerror
--// (System_Interface.Error.Errno))));
--/ elsif TeleGen2 and then Unix then
--// (Error_Messages.Sys_Error_Message
--// (Error_Messages.Errno)));
--/ else
--// (Need_Errno_String));
--/ end if;
--// Status := Failed;
--// return;
--// end if;
--//
--// ----Now try to connect our socket to the X server's socket.
--//
--// if Connect (Fd, Sock'Address, Sock'Size / 8) < 0 then
--// Void := Close (Fd);
--// Err (Error, X_Get_Error_String ("XlibError", "ConnectFailed",
--// "System Connect call failed:") &
--// ' ' & To_X_String
--/ if Cdf_Hpux then
--// (Unix_Base_Types.To_String
--// (C_Library_Interface.Error.Strerror
--// (System_Interface.Error.Errno))));
--/ elsif TeleGen2 and then Unix then
--// (Error_Messages.Sys_Error_Message
--// (Error_Messages.Errno)));
--/ else
--// (Need_Errno_String));
--/ end if;
--// Status := Failed;
--// return;
--// end if;
--//
--// ----We made it. Return the open connection.
--//
--// Host_Addr := new Host_Id'(Host_Num);
--// Connection := Fd;
--// Status := Successful;
--// return;
--//
--// end Make_Host_Connection;
--//
--/ end if; -- TeleGen2 and then Unix
--\f
procedure Internal_X_Connect_Display
(Display_Name : X_String;
Expanded_Name : out X_String_Pointer;
Display_Num : out U_Char;
Screen_Num : out X_Screen_Number;
Family : out X_Host_Protocol_Family;
Server_Addr : out X_Network_Host_Address;
Connection : out X_Network_Connection;
Status : out X_Status;
Error : in out X_Error_String) is
------------------------------------------------------------------------------
-- Display_Name - Specifies what machine/screen/number to connect to
-- Expanded_Name - Receives the full specification of the connection made
-- or None_X_String_Pointer on errors
-- Display_Num - Receives the display number of the connection
-- Screen_Num - Receives the screen number of the connection
-- Family - Receives the network family type of the connection
-- Status - Receives an indication of the success/failure
-- Error - Receives a string indicating any failure
--
-- Attempts to connect to server, given display name. Returns network connection
-- id. Status = Failed if connection fails. The expanded display name
-- of the form hostname:number.scr ("::" if DECnet) is returned in a result
-- parameter. The screen number to use is also returned.
-- The Display_Name may be of the following format:
--
-- [hostname] : [:] displaynumber [.screennumber]
--
-- The second colon indicates a DECnet style name. No hostname is interpreted
-- as the most efficient local connection to a server on the same machine.
-- This is usually:
--
-- - shared memory
-- - local stream
-- - UNIX domain socket
-- - TCP to local host
------------------------------------------------------------------------------
Host_First : S_Natural; -- Start of host name
Host_Last : S_Natural; -- End of host name
First : S_Natural; -- Used in string searching
Last : S_Long; -- Used in string searching
Current : S_Long; -- Used in string searching
Decnet : Boolean;
Fd : Connection_Id; -- Network connection
--/ if Cdf_Hpux then
--// Void : S_Long;
--/ elsif TeleGen2 and then Unix then
--// Void : S_Long;
--/ end if;
Ldisplay_Num : U_Char; -- Display number
Scn_Num : X_Screen_Number; -- Screen number
Lserver_Addr : X_Network_Host_Address;
Succ : X_Status;
procedure Search (Skip : X_Character; Want : X_Character) is
begin
----If we've used up the entire string then set First..Last to empty.
if Current >= Display_Name'Last then
Last := Display_Name'Last;
First := Last + 1;
return;
end if;
----Skip over Skip characters; watch for end of string.
Current := Current + 1;
while Display_Name (Current) = Skip loop
if Current >= Display_Name'Last then
Last := First - 1;
return;
end if;
Current := Current + 1;
end loop;
----Scan remainder of string looking for the Want character.
First := Current;
Last := Display_Name'Last;
for I in First .. Last loop
if Display_Name (I) = Want then
----Remember where we left off.
Current := I;
Last := I - 1;
return;
end if;
end loop;
----Remember that string is now all used up.
Current := Display_Name'Last;
end Search;
begin
----Init our OUT parameters.
Expanded_Name := None_X_String_Pointer;
Display_Num := 0;
Screen_Num := 0;
Family := None_X_Host_Protocol_Family;
Connection.Fd := None_Connection_Id;
Connection.Fd_Error := Ok;
Server_Addr := None_X_Network_Host_Address;
Err (Error, "");
----Locate the host name in our Display_Name string. The string looks like this
-- [ host ] [ : ]+ [ display ] [ . [ screen ] ]
-- "[]" indicate optional parts; "[]+" indicates one or more occurrences of
-- "host" is anything that isn't a ":" and is valid as a host name
-- "display" is a decimal number
-- "screen" is a decimal number
Current := Display_Name'First - 1;
Search (' ', ':');
Host_First := First;
Host_Last := Last;
----We don't support DECnet on R1000's; at least not yet.
Decnet := Current + 1 <= Display_Name'Last and then
Display_Name (Current .. Current + 1) = "::";
Family := Family_Internet;
if Decnet then
Err (Error, X_Get_Error_String
("XlibError", "DECnetUnsup",
"DECnet connections are not currently supported:") &
' ' & Display_Name);
Status := Failed;
return;
end if;
----Now locate the display number. It follows the host name which was
-- terminated by a ":" if the display number is specified.
Search (':', '.');
if First > Last then -- If no display number given
Ldisplay_Num := 0; -- No display given; use default.
else
begin
Ldisplay_Num := U_Char'Value
(To_String (Display_Name (First .. Last)));
exception
when Constraint_Error =>
Err (Error, X_Get_Error_String
("XlibError", "CEDpyNum",
"Constraint_Error raised while " &
"converting display number:") &
' ' & Display_Name (First .. Last));
Status := Failed;
return;
end;
end if;
Display_Num := Ldisplay_Num;
----Now locate the screen number. It follows the display number which was
-- terminated by a "." if the screen number is specified.
Search ('.', Nul);
if First > Last then -- If no screen number given
Scn_Num := 0; -- No screen given; use default.
else
begin
Scn_Num := X_Screen_Number'Value
(To_String (Display_Name (First .. Last)));
exception
when Constraint_Error =>
Err (Error, X_Get_Error_String
("XlibError", "CEScrNum",
"Constraint_Error raised while " &
"converting screen number:") &
' ' & Display_Name (First .. Last));
Status := Failed;
return;
end;
end if;
Screen_Num := Scn_Num;
----Watch for junque.
if Last < Display_Name'Last and then
Display_Name (Last + 1 .. Display_Name'Last) /=
(Last + 1 .. Display_Name'Last => Nul) and then
Display_Name (Last + 1 .. Display_Name'Last) /=
(Last + 1 .. Display_Name'Last => ' ') then
Err (Error,
X_Get_Error_String
("XlibError", "DNGarbage",
"Garbage characters after the display name :") & " [" &
Display_Name (Last + 1 .. Display_Name'Last) & "]");
Status := Failed;
return;
end if;
----Try to open a socket onto the network of the host. We connect to ourselves
-- if no host name was specified.
if Host_First > Host_Last or else -- If no host name given.
Display_Name (Host_First .. Host_Last) = "local" then
begin
declare -- No host given; use local host
Host : constant X_String := X_Env_Get_Host_Name;
begin
Make_Host_Connection (Host, Ldisplay_Num, Fd,
Lserver_Addr, Succ, Error);
end;
exception
--/ if R1000 then
when Transport_Name.Undefined =>
Err (Error, X_Get_Error_String
("XlibError", "UnknownHost", Unknown_Host) &
' ' & Display_Name (Host_First .. Host_Last));
Status := Failed;
return;
--/ end if;
when others =>
raise;
end;
else -- Use his explicit host name
Make_Host_Connection (Display_Name (Host_First .. Host_Last),
Ldisplay_Num, Fd, Lserver_Addr, Succ, Error);
end if;
----Make sure that we have a network connection.
if Succ = Failed then
Free_X_Network_Host_Address (Lserver_Addr);
Status := Failed;
return; -- Reason for failure already in Error.
end if;
----Return the connection id string if the connection succeeded. Rebuild the
-- expanded id and return it.
declare
Dn : constant String := U_Char'Image (Ldisplay_Num);
Sn : constant String := S_Natural'Image
(X_Screen_Number'Pos (Scn_Num));
begin
Expanded_Name :=
new X_String'(Display_Name (Host_First .. Host_Last) &
':' & To_X_String (Dn (Dn'First + 1 .. Dn'Last)) &
'.' & To_X_String (Sn (Sn'First + 1 .. Sn'Last)));
exception
when others =>
Free_X_Network_Host_Address (Lserver_Addr);
--/ if R1000 and R1000_Xlib_Only then
--// Transport.Disconnect (Fd);
--// Transport.Close (Fd);
--/ elsif R1000 and not R1000_Xlib_Only then
abort Fd.Reader;
Transport.Disconnect (Fd.Connection);
Transport.Close (Fd.Connection);
Free_Connection_Id (Fd);
--/ elsif Unix then
--// Void := Close (Fd);
--/ else
--// Something;
--/ end if;
raise;
end;
Server_Addr := Lserver_Addr;
Connection.Fd := Fd;
Status := Successful;
end Internal_X_Connect_Display;
--\f
procedure Internal_X_Disconnect_Display
(Connection : in out X_Network_Connection) is
------------------------------------------------------------------------------
-- Disconnect from server.
------------------------------------------------------------------------------
--/ if R1000 and R1000_Xlib_Only then
--// begin
--//
--// Transport.Disconnect (Connection.Fd);
--// Transport.Close (Connection.Fd);
--/ elsif R1000 and not R1000_Xlib_Only then
begin
if Connection.Fd /= null then
abort Connection.Fd.Reader;
Transport.Disconnect (Connection.Fd.Connection);
Transport.Close (Connection.Fd.Connection);
Free_Connection_Id (Connection.Fd);
end if;
--/ else
--// Void : S_Long;
--// begin
--//
--// Void := Close (Connection.Fd);
--/ end if;
end Internal_X_Disconnect_Display;
--\f
begin
----Register debugging "junque". Xlbmp_Internal is, of necessity, used by any
-- interesting Xlib program. Without Xlbmp_Internal you can't talk to the
-- X Server so you can't be "interesting". So, register the debugging imagers
-- here. This guarantees that this code isn't "forgotten" by some application
-- and it will make debugging easier for them.
Xlbmp_Debugger.Register_Debugging_Imagers;
end Xlbmp_Internal;