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 - downloadIndex: ┃ B T ┃
Length: 43620 (0xaa64) Types: TextFile Names: »B«
└─⟦85b835f43⟧ Bits:30000549 8mm tape, Rational 1000, Xlib rev 6.00 └─ ⟦0c20f784e⟧ »DATA« └─⟦1abbe589f⟧ └─⟦059497ac5⟧ └─⟦this⟧
with Xlbt_Arithmetic; use Xlbt_Arithmetic; with Xlbt_Basic; use Xlbt_Basic; with Xlbt_Exceptions; use Xlbt_Exceptions; with Xlbt_Request; use Xlbt_Request; with Xlbip_Internal; use Xlbip_Internal; with Xlbmt_Network_Types; use Xlbmt_Network_Types; with Xlbmp_Internal; use Xlbmp_Internal; package body Xlbmp_Put is ------------------------------------------------------------------------------ -- X Library X Server Put Routines -- -- Xlbmp_Put - Send info to the X Server ------------------------------------------------------------------------------ -- Copyright 1989 - 1991 by Rational, Santa Clara, California. -- -- 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 name of Rational not be used in -- advertising or publicity pertaining to distribution of the software -- without specific, written prior permission. -- -- Rational disclaims all warranties with regard to this software, including -- all implied warranties of merchantability and fitness, in no event shall -- 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 procedure Put_Request (Display : X_Display; Req : Request) is ------------------------------------------------------------------------------ -- For X_Request's only. Do not use for ordinary private types. -- -- Put data into the buffer going to a particular display. All X requests -- are always a multiple of 32 bits (4 bytes) in length. If the data -- does not fit into the buffer then the buffer is flushed first. -- Display.Last_Req is not set; that is up to the caller. -- Request - this is the type of data that needs to be sent -- Request_Size - all X protocol requests are 4*N bytes long, this value -- corresponds to the number of X_Raw_Data items -- Cvt - converts the data to X_Raw_Data -- Display - display to receive the request -- Req - the request to send ------------------------------------------------------------------------------ Last_Byte : X_Raw_Data_Index; begin ----If this fails then the previous request left the buffer on a non-word -- boundary. That would mean that we are harboring a bug somewhere. --/ if DEBUG then if Request_Size rem 4 /= 0 then raise X_Library_Confusion; elsif Display.Output.Used rem 4 /= 0 then raise X_Library_Confusion; end if; --/ end if; ----If there is a request in the Display.Last_Req buffer then he must be flushed -- before we can be placed. if Display.Last_Request.Kind /= Invalid_Request then Internal_X_Flush_Last_Request (Display); end if; ----If this request will not fit in the buffer then flush the buffer. Last_Byte := Display.Output.Used + Request_Size; if Last_Byte > Display.Output.Data'Last then Internal_X_Flush_Display (Display); Last_Byte := Request_Size; end if; ----Put the data into the buffer. To_Raw (Display.Output.Data (Display.Output.Used + 1 .. Last_Byte), Req); Display.Output.Used := Last_Byte; begin Display.Request := Display.Request + 1; exception when Constraint_Error => Display.Request := (Display.Request - 16#7F00_0000#) + 1; Display.Last_Request_Read := Display.Last_Request_Read - 16#7F00_0000#; end; end Put_Request; --\f procedure Put_Request_Extra (Display : X_Display; Req : Request; Extra : S_Natural) is ------------------------------------------------------------------------------ -- For Discrete and ordinary Private types. -- -- Put data into the buffer going to a particular display. All X requests -- are always a multiple of 32 bits (4 bytes) in length. If the data -- does not fit into the buffer then the buffer is flushed first. -- Display.Last_Req is not set; that is up to the caller. -- Request - this is the type of data that needs to be sent -- Request_Size - all X protocol requests are 4*N bytes long, this value -- corresponds to the number of X_Raw_Data items -- To_Raw - converts the data to X_Raw_Data -- Display - display to receive the request -- Req - the request to send -- Extra - We are making a request to the server and we need the -- buffer space for this Request object plus we will need -- Extra bytes in the same buffer for data that follows -- and is part of the request. ------------------------------------------------------------------------------ Extra_Bytes : X_Raw_Data_Index := X_Raw_Data_Index ((Extra + 3) / 4 * 4); Last_Byte : X_Raw_Data_Index; begin ----If this fails then the previous request left the buffer on a non-word -- boundary. That would mean that we are harboring a bug somewhere. if Request_Size rem 4 /= 0 then raise X_Library_Confusion; elsif Display.Output.Used rem 4 /= 0 then raise X_Library_Confusion; end if; ----If there is a request in the Display.Last_Req buffer then he must be flushed -- before we can be placed. if Display.Last_Request.Kind /= Invalid_Request then Internal_X_Flush_Last_Request (Display); end if; ----If this request will not fit in the buffer then flush the buffer. Last_Byte := Display.Output.Used + Request_Size; if Last_Byte + Extra_Bytes > Display.Output.Data'Last then Internal_X_Flush_Display (Display); Last_Byte := Request_Size; end if; ----Put the data into the buffer. The Extra data is placed later. To_Raw (Display.Output.Data (Display.Output.Used + 1 .. Last_Byte), Req); Display.Output.Used := Last_Byte; begin Display.Request := Display.Request + 1; exception when Constraint_Error => Display.Request := (Display.Request - 16#7F00_0000#) + 1; Display.Last_Request_Read := Display.Last_Request_Read - 16#7F00_0000#; end; end Put_Request_Extra; --\f procedure Put_Data_Private (Display : X_Display; D : Original) is ------------------------------------------------------------------------------ -- For Discrete and ordinary Private types. -- -- Put data into the buffer going to a particular display. All X requests -- are always a multiple of 32 bits (4 bytes) in length. If the data -- does not fit into the buffer then the buffer is flushed first. -- Display.Last_Req is not set; that is up to the caller. -- Original - this is the type of data that needs to be sent -- Original_Size - all X protocol requests are 32 bytes long, this value -- corresponds to the number of X_Raw_Data items; always -- a multiple of 4 bytes. -- To_Raw - converts the data to X_Raw_Data -- Display - display to receive the request -- D - the data to send ------------------------------------------------------------------------------ Last_Byte : X_Raw_Data_Index; begin ----If this fails then the previous request left the buffer on a non-word -- boundary. That would mean that we are harboring a bug somewhere. if Display.Output.Used rem 4 /= 0 then raise X_Library_Confusion; end if; ----If this request will fit into the buffer (usual case) then just place it -- there. Last_Byte := Display.Output.Used + Original_Size; if Last_Byte <= Display.Output.Data'Last then To_Raw (Display.Output.Data (Display.Output.Used + 1 .. Last_Byte), D); ----This request will not fit in the buffer; flush the buffer. else Internal_X_Flush_Display (Display); ----If this request will fit into the buffer now (usual case) then just do that. if Original_Size <= Display.Output.Data'Last then Last_Byte := Original_Size; To_Raw (Display.Output.Data (1 .. Last_Byte), D); ----The caller is shipping something very large. Allocate some heap to use -- as a buffer (we don't want to rely upon the stack being large enough; there -- is a Storage_Error exception but there is no Stack_Overflow exception). else declare Raw : X_Raw_Data_List; Rawi : X_Raw_Data_Index := 1; begin ----Convert the data into Raw form and put it out a bit at a time. Raw := new X_Raw_Data_Array (1 .. Original_Size); To_Raw (Raw.all, D); for I in reverse 1 .. Original_Size / Display.Output.Data'Last loop Display.Output.Data := Raw (Rawi .. Rawi - 1 + Display.Output.Data'Last); Display.Output.Used := Display.Output.Data'Last; Internal_X_Flush_Display (Display); Rawi := Rawi + Display.Output.Data'Last; end loop; ----Put out the last piece of data and return. Last_Byte := Original_Size - Rawi + 1; Display.Output.Data (1 .. Last_Byte) := Raw (Rawi .. Original_Size); Free_X_Raw_Data_List (Raw); end; end if; end if; Display.Output.Used := Last_Byte; end Put_Data_Private; --\f procedure Put_Data_Private_Unaligned (Display : X_Display; D : Original) is ------------------------------------------------------------------------------ -- For Discrete and ordinary Private types. -- -- Put data into the buffer going to a particular display. This is only used -- for those portions of some requests where we must create the requests -- piecemeal out of pieces that are not multiples of 4-bytes in length. -- If the data does not fit into the buffer then the buffer is flushed first. -- Display.Last_Req is not set; that is up to the caller. -- Original - this is the type of data that needs to be sent -- Original_Size - all X protocol requests are 4*N bytes long, this value -- corresponds to the number of X_Raw_Data items -- To_Raw - converts the data to X_Raw_Data -- Display - display to receive the request -- D - the data to send ------------------------------------------------------------------------------ Last_Byte : X_Raw_Data_Index; Unal : X_Raw_Data_Array (1 .. 4); Unali : X_Raw_Data_Index; begin ----If our caller is following the rules then the space required for this data -- was "allocated" (allowed for) by a call on Put_Request_Extra. Just stuff -- the data into the buffer. Of course, the buffer may be smaller than the -- total request... ----If this request will fit into the buffer (usual case) then just place it -- there. if Original_Size <= Display.Output.Data'Last - Display.Output.Used then Last_Byte := Display.Output.Used + X_Raw_Data_Index (Original_Size); To_Raw (Display.Output.Data (Display.Output.Used + 1 .. Last_Byte), D); Display.Output.Used := Last_Byte; return; end if; ----This request will not fit in the buffer; flush the buffer. Only flush -- a multiple of 4 bytes. Unali := Display.Output.Used rem 4; Display.Output.Used := Display.Output.Used - Unali; Unal (1 .. Unali) := Display.Output.Data (Display.Output.Used + 1 .. Display.Output.Used + Unali); Internal_X_Flush_Display (Display); ----If the request will fit into the buffer now (usual case) then just do that. Last_Byte := Unali + X_Raw_Data_Index (Original_Size); if Last_Byte <= Display.Output.Data'Last then Display.Output.Data (1 .. Unali) := Unal (1 .. Unali); To_Raw (Display.Output.Data (Unali + 1 .. Last_Byte), D); Display.Output.Used := Last_Byte; return; end if; ----The caller is shipping something very large. Allocate some heap to use -- as a buffer (we don't want to rely upon the stack being large enough; there -- is a Storage_Error exception but there is no Stack_Overflow exception). -- Note: We cannot ship something whose Original_Size > X_Raw_Data_Index'Last. -- We can expect that to be at lease 32*1024 bytes so we won't worry about it -- until it bites us. A workaround for the caller would be to convert to -- a u_char_array first and then transmit that. declare Raw : X_Raw_Data_List; Rawi : X_Raw_Data_Index := 1; begin ----Convert the data into Raw form and put it out a bit at a time. Raw := new X_Raw_Data_Array (1 .. Last_Byte); Raw (1 .. Unali) := Unal (1 .. Unali); To_Raw (Raw (Unali + 1 .. Last_Byte), D); for I in reverse 1 .. Last_Byte / Display.Output.Data'Last loop Display.Output.Data := Raw (Rawi .. Rawi + Display.Output.Data'Last - 1); Display.Output.Used := Display.Output.Data'Last; Internal_X_Flush_Display (Display); Rawi := Rawi + Display.Output.Data'Last; end loop; ----Put out the last piece of data and return. Last_Byte := Last_Byte - Rawi + 1; Display.Output.Data (1 .. Last_Byte) := Raw (Rawi .. Raw'Last); Display.Output.Used := Last_Byte; Free_X_Raw_Data_List (Raw); return; exception when others => Free_X_Raw_Data_List (Raw); raise; end; end Put_Data_Private_Unaligned; --\f procedure Put_Large_Data_1d (Display : X_Display; D : Original_Array) is ------------------------------------------------------------------------------ -- For one-dimensional array types where the element type is "large". A -- "large" type is any type whose 'Size is a multiple of 32 bits. -- -- If you get a Constraint_Error when elaborating this generic then you have -- tried to instantiate it with a type whose 'Size is not N*32. -- -- Put data into the buffer going to a particular display. All X requests -- are always a multiple of 32 bits (4 bytes) in length. If the data -- does not fit into the buffer then the buffer is flushed first. -- Display.Last_Req is not set; that is up to the caller. -- Original - this is the type of data that needs to be sent -- Original_Size - all X protocol requests are 4*N bytes long, this value -- corresponds to the number of X_Raw_Data items -- Index - this is the index type for the array type -- Original_Array - this is the array type -- To_Raw - converts the data to X_Raw_Data -- Display - display to receive the request -- D - the data to send ------------------------------------------------------------------------------ Total_Size : S_Natural := S_Natural (Original_Size) * D'Length; Last_Byte : X_Raw_Data_Index; Next : S_Long; Incr : S_Long; begin ----If this fails then the previous request left the buffer on a non-word -- boundary. That would mean that we are harboring a bug somewhere. --/ if DEBUG then if Display.Output.Used rem 4 /= 0 then raise X_Library_Confusion; elsif Total_Size = 0 then return; end if; --/ end if; ----If this request will fit into the buffer (usual case) then just place it -- there. if S_Long (Display.Output.Data'Last - Display.Output.Used) >= Total_Size then Last_Byte := Display.Output.Used + X_Raw_Data_Index (Total_Size); To_Raw (Display.Output.Data (Display.Output.Used + 1 .. Last_Byte), D); Display.Output.Used := Last_Byte; return; end if; ----This request will not fit in the buffer; flush the buffer. Internal_X_Flush_Display (Display); ----If this request will fit into the buffer now (usual case) then just do that. if Total_Size <= S_Long (Display.Output.Data'Last) then Last_Byte := X_Raw_Data_Index (Total_Size); To_Raw (Display.Output.Data (1 .. Last_Byte), D); Display.Output.Used := Last_Byte; return; end if; ----The caller is shipping something very large. Put out the array elements -- a few at a time. Next := S_Long (D'First); Incr := S_Long (Display.Input.Data'Last / Original_Size); Last_Byte := Original_Size * X_Raw_Data_Index (Incr); ----First we write them as complete Display.Input.Data buffer-fulls at a time. while S_Long (D'Last) - Next >= Incr loop To_Raw (Display.Output.Data (1 .. Last_Byte), D (Index (Next) .. Index (Next + Incr - 1))); Display.Output.Used := Last_Byte; Internal_X_Flush_Display (Display); Next := Next + Incr; end loop; ----Finally we write whatever is left to write. if Next <= S_Long (D'Last) then Last_Byte := Original_Size * X_Raw_Data_Index (S_Long (D'Last) - Next + 1); To_Raw (Display.Output.Data (1 .. Last_Byte), D (Index (Next) .. D'Last)); Display.Output.Used := Last_Byte; end if; end Put_Large_Data_1d; --\f procedure Put_Small_Data_1d (Display : X_Display; D : Original_Array) is ------------------------------------------------------------------------------ -- For one-dimensional array types where the element type is "small". A -- "small" type is any type whose 'Size is less than 32 bits. This is -- expected to be used for 8 and 16 bit data types. Other sizes of -- data will not probably work properly. -- -- If you get a Constraint_Error when elaborating this generic then you have -- tried to instantiate it with a type whose 'Size is not N*32. -- -- Put data into the buffer going to a particular display. All X requests -- are always a multiple of 32 bits (4 bytes) in length. If the data -- does not fit into the buffer then the buffer is flushed first. -- Display.Last_Req is not set; that is up to the caller. -- Original - this is the type of data that needs to be sent -- Original_Size - all X protocol requests are 4*N bytes long, this value -- corresponds to the number of X_Raw_Data items -- Index - this is the index type for the array type -- Original_Array - this is the array type -- To_Raw - converts the data to X_Raw_Data -- Display - display to receive the request -- D - the data to send ------------------------------------------------------------------------------ Total_Size : S_Natural := S_Natural (Original_Size) * D'Length; Last_Byte : X_Raw_Data_Index; Next : S_Long; Incr : S_Long; begin ----If this fails then the previous request left the buffer on a non-word -- boundary. That would mean that we are harboring a bug somewhere. if Display.Output.Used rem 4 /= 0 then raise X_Library_Confusion; elsif Total_Size = 0 then return; end if; ----If this request will fit into the buffer (usual case) then just place it -- there. if S_Long (Display.Output.Data'Last - Display.Output.Used) >= Total_Size then Last_Byte := Display.Output.Used + X_Raw_Data_Index (Total_Size); To_Raw (Display.Output.Data (Display.Output.Used + 1 .. Last_Byte), D); goto Modulo_4; end if; ----This request will not fit in the buffer; flush the buffer. Internal_X_Flush_Display (Display); ----If this request will fit into the buffer now (usual case) then just do that. if Total_Size <= S_Long (Display.Output.Data'Last) then Last_Byte := X_Raw_Data_Index (Total_Size); To_Raw (Display.Output.Data (1 .. Last_Byte), D); goto Modulo_4; end if; ----The caller is shipping something very large. Put out the array elements -- a few at a time. Next := S_Long (D'First); Incr := S_Long (Display.Input.Data'Last / Original_Size); Last_Byte := Original_Size * X_Raw_Data_Index (Incr); ----First we write them as complete Display.Input.Data buffer-fulls at a time. while S_Long (D'Last) - Next >= Incr loop To_Raw (Display.Output.Data (1 .. Last_Byte), D (Index (Next) .. Index (Next + Incr - 1))); Display.Output.Used := Last_Byte; Internal_X_Flush_Display (Display); Next := Next + Incr; end loop; ----Finally we write whatever is left to write. if Next <= S_Long (D'Last) then Last_Byte := Original_Size * X_Raw_Data_Index (S_Long (D'Last) - Next + 1); To_Raw (Display.Output.Data (1 .. Last_Byte), D (Index (Next) .. D'Last)); else Last_Byte := 0; end if; ----Pad the output buffer to a modulo-4 boundary. <<Modulo_4>> null; case Last_Byte rem 4 is when 1 => Last_Byte := Last_Byte + 3; Display.Output.Data (Last_Byte - 2) := 0; Display.Output.Data (Last_Byte - 1) := 0; Display.Output.Data (Last_Byte - 0) := 0; when 2 => Last_Byte := Last_Byte + 2; Display.Output.Data (Last_Byte - 1) := 0; Display.Output.Data (Last_Byte - 0) := 0; when 3 => Last_Byte := Last_Byte + 1; Display.Output.Data (Last_Byte - 0) := 0; when others => null; end case; Display.Output.Used := Last_Byte; end Put_Small_Data_1d; --\f procedure Put_Small_Data_1d_Unaligned (Display : X_Display; D : Original_Array) is ------------------------------------------------------------------------------ -- For one-dimensional array types where the element type is "small". A -- "small" type is any type whose 'Size is less than 32 bits. This is -- expected to be used for 8 and 16 bit data types. Other sizes of -- data will not probably work properly. -- -- If you get a Constraint_Error when elaborating this generic then you have -- tried to instantiate it with a type whose 'Size is not N*32. -- -- Put data into the buffer going to a particular display. All X requests -- are always a multiple of 32 bits (4 bytes) in length. This routine does -- not preserve that 4-byte alignment requirement. Callers of this routine -- are required to make their request a multiple of 4-bytes when they are -- finished. If the data does not fit into the buffer then the buffer is -- flushed first. Display.Last_Req is not set; that is up to the caller. -- Original - this is the type of data that needs to be sent -- Index - this is the index type for the array type -- Original_Array - this is the array type -- To_Raw - converts the data to X_Raw_Data -- Original_Size - all X protocol requests are 4*N bytes long, this value -- corresponds to the number of X_Raw_Data items required -- to represent a single Original item -- Less_Than_32 - causes Constraint_Error if Original is of an inappropriate -- 'Size -- Display - display to receive the request -- D - the data to send ------------------------------------------------------------------------------ Total_Size : S_Natural := S_Natural (Original_Size) * D'Length; Last_Byte : X_Raw_Data_Index; Next : S_Long; Incr : S_Long; begin ----If this request will fit into the buffer (usual case) then just place it -- there. if Total_Size = 0 then return; elsif S_Long (Display.Output.Data'Last - Display.Output.Used) >= Total_Size then Last_Byte := Display.Output.Used + X_Raw_Data_Index (Total_Size); To_Raw (Display.Output.Data (Display.Output.Used + 1 .. Last_Byte), D); Display.Output.Used := Last_Byte; return; end if; ----This request will not fit in the buffer; flush the buffer. Internal_X_Flush_Display (Display); ----If this request will fit into the buffer now (usual case) then just do that. if Total_Size <= S_Long (Display.Output.Data'Last) then Last_Byte := X_Raw_Data_Index (Total_Size); To_Raw (Display.Output.Data (1 .. Last_Byte), D); Display.Output.Used := Last_Byte; return; end if; ----The caller is shipping something very large. Put out the array elements -- a few at a time. Note: This only works if Original_Size is not larger -- than X_Raw_Data_Index'Last. In a case like that the caller can always -- convert to a U_Char_Array and then transmit that. Next := S_Long (D'First); Incr := S_Long (Display.Input.Data'Last / Original_Size); Last_Byte := Original_Size * X_Raw_Data_Index (Incr); ----First we write them as complete Display.Input.Data buffer-fulls at a time. while S_Long (D'Last) - Next >= Incr loop To_Raw (Display.Output.Data (1 .. Last_Byte), D (Index (Next) .. Index (Next + Incr - 1))); Display.Output.Used := Last_Byte; Internal_X_Flush_Display (Display); Next := Next + Incr; end loop; ----Finally we write whatever is left to write. if Next <= S_Long (D'Last) then Last_Byte := Original_Size * X_Raw_Data_Index (S_Long (D'Last) - Next + 1); To_Raw (Display.Output.Data (1 .. Last_Byte), D (Index (Next) .. D'Last)); else Last_Byte := 0; end if; Display.Output.Used := Last_Byte; end Put_Small_Data_1d_Unaligned; --\f procedure Put_Data_2d (Display : X_Display; D : Original_Array) is ------------------------------------------------------------------------------ -- For two-dimensional array types where the element type is 8, 16, or N*32 -- bits in length. -- -- If you get a Constraint_Error when elaborating this generic then you have -- tried to instantiate it with a type whose 'Size is not N*8. -- -- Put data into the buffer going to a particular display. All X requests -- are always a multiple of 32 bits (4 bytes) in length. If the data -- does not fit into the buffer then the buffer is flushed first. -- Display.Last_Req is not set; that is up to the caller. -- Original - this is the type of data that needs to be sent -- Original_Size - all X protocol requests are 4*N bytes long, this value -- corresponds to the number of X_Raw_Data items -- Index1 - this is the first index type for the array type -- Index2 - this is the second index type for the array type -- Original_Array - this is the array type -- To_Raw - converts the data to X_Raw_Data -- Display - display to receive the request -- D - the data to send ------------------------------------------------------------------------------ Last_Byte : X_Raw_Data_Index; Total_Size : S_Long := S_Long (Original_Size) * D'Length (1) * D'Length (2); begin ----If this fails then the previous request left the buffer on a non-word -- boundary. That would mean that we are harboring a bug somewhere. if Display.Output.Used rem 4 /= 0 then raise X_Library_Confusion; elsif Total_Size = 0 then return; end if; ----If this request will fit into the buffer (usual case) then just place it -- there. if Total_Size <= S_Long (Display.Output.Data'Last - Display.Output.Used) then Last_Byte := Display.Output.Used + X_Raw_Data_Index (Total_Size); To_Raw (Display.Output.Data (Display.Output.Used + 1 .. Last_Byte), D); goto Modulo_4; end if; ----This request will not fit in the buffer; flush the buffer. Internal_X_Flush_Display (Display); ----If this request will fit into the buffer now (usual case) then just do that. if Total_Size <= S_Long (Display.Output.Data'Last) then Last_Byte := X_Raw_Data_Index (Total_Size); To_Raw (Display.Output.Data (1 .. Last_Byte), D); goto Modulo_4; end if; ----The caller is shipping something very large. Put out the array elements -- one at a time; you can't slice a 2-D array in Ada. declare Raw : X_Raw_Data_Array (1 .. Original_Size); Raw_Tmp : X_Raw_Data_Array (1 .. 3); Raw_Tmpi : X_Raw_Data_Index; begin Last_Byte := 0; for I in D'Range (1) loop for J in D'Range (2) loop To_Raw (Raw, D (I, J)); if Display.Output.Data'Last - Last_Byte < Original_Size then ----When we must flush the buffer, make sure we flush multiples of 4 bytes. Raw_Tmpi := Last_Byte rem 4; Display.Output.Used := Last_Byte - Raw_Tmpi; Raw_Tmp (1 .. Raw_Tmpi) := Display.Output.Data (Display.Output.Used + 1 .. Display.Output.Used + Raw_Tmpi); Internal_X_Flush_Display (Display); Display.Output.Data (1 .. Raw_Tmpi) := Raw_Tmp (1 .. Raw_Tmpi); Last_Byte := Raw_Tmpi; end if; ----Put the next element into the buffer. Display.Output.Data (Last_Byte + 1 .. Last_Byte + Original_Size) := Raw; Last_Byte := Last_Byte + Original_Size; end loop; end loop; end; ----Pad the output buffer to a modulo-4 boundary. <<Modulo_4>> null; case Last_Byte rem 4 is when 1 => Last_Byte := Last_Byte + 3; Display.Output.Data (Last_Byte - 2) := 0; Display.Output.Data (Last_Byte - 1) := 0; Display.Output.Data (Last_Byte - 0) := 0; when 2 => Last_Byte := Last_Byte + 2; Display.Output.Data (Last_Byte - 1) := 0; Display.Output.Data (Last_Byte - 0) := 0; when 3 => Last_Byte := Last_Byte + 1; Display.Output.Data (Last_Byte - 0) := 0; when others => null; end case; Display.Output.Used := Last_Byte; end Put_Data_2d; --\f procedure Reserve_Request_Large_1d (Display : X_Display; Max_Spaces : S_Natural; Req : Request; D : Original_Array; Reservation : out X_Raw_Data_Index; Spaces_Left : out S_Natural) is ------------------------------------------------------------------------------ -- For Poly X_Request's with one dimensional array arguments only. -- Do not use this for ordinary private types or for arrays of "small" types. -- -- Called in an attempt to a) reserve space for a request record and b) to -- begin placing the array data into the output buffer. Allocates space in -- the Display.Output buffer for the request and then allocates space in the -- buffer for the array data. The array data is copied into the buffer. The -- request is not copied. Use the Place_Reserved_Request generic to do that. -- This is for the use of the various Poly requests where adjacent requests may -- be joined together to form a smaller number of longer requests. -- -- Returns the reserved position for the request and the maximum number of -- further array elements that can be placed into the buffer. -- -- If you get a Constraint_Error when elaborating this generic then you have -- tried to instantiate it with a type whose 'Size is not N*32. -- -- Put data into the buffer going to a particular display. All X requests -- are always a multiple of 32 bits (4 bytes) in length. If the data -- does not fit into the buffer then the buffer is flushed first. -- Display.Last_Req is not set; that is up to the caller. -- Original - this is the type of data that needs to be sent -- Index - this is the index type for the array type -- Original_Array - this is the array type -- Request - this is the type of data that needs to be sent -- To_Raw - converts the data to X_Raw_Data -- To_Raw - converts the data to X_Raw_Data -- Request_Size - all X protocol requests are 4*N bytes long, this value -- corresponds to the number of X_Raw_Data items required -- to represent the Request -- Multiple_Of_32 - causes Constraint_Error if Request is of an inappropriate -- 'Size -- Original_Size - all X protocol requests are 4*N bytes long, this value -- corresponds to the number of X_Raw_Data items required -- to represent a single Original item -- Original_Multiple_Of_32 - causes Constraint_Error if Original is of an -- inappropriate 'Size -- Display - display to receive the request -- Req - the X_Request to send ------------------------------------------------------------------------------ Total_Size : S_Natural := S_Natural (Original_Size) * D'Length; Last_Byte : X_Raw_Data_Index; Next : S_Long; Incr : S_Long; begin ----If this fails then the previous request left the buffer on a non-word -- boundary. That would mean that we are harboring a bug somewhere. -- We only reserve requests that fit into the buffer. --/ if DEBUG then if Request_Size rem 4 /= 0 then raise X_Library_Confusion; elsif Display.Output.Used rem 4 /= 0 then raise X_Library_Confusion; elsif Max_Spaces <= D'Length then raise X_Library_Confusion; end if; --/ end if; ----If there is a request in the Display.Last_Req buffer then he must be flushed -- before we can be placed. if Display.Last_Request.Kind /= Invalid_Request then Internal_X_Flush_Last_Request (Display); end if; ----If this request will fit into the buffer then shove it in and return. if Total_Size <= S_Long (Display.Output.Data'Last - Display.Output.Used - Request_Size) then ----Calculate the last byte that will be used. Then calculate the number -- of spaces that remain in the buffer for new array elements. Last_Byte := Display.Output.Used + Request_Size + X_Raw_Data_Index (Total_Size); Incr := S_Long (Display.Output.Data'Last - Last_Byte / Original_Size); Incr := Min (Max_Spaces - D'Length, Incr); Spaces_Left := Incr; ----If there are no more spaces left then shove the request into the buffer. if Incr = 0 then To_Raw (Display.Output.Data (Display.Output.Used + 1 .. Display.Output.Used + Request_Size), Req); Reservation := 0; else Reservation := Display.Output.Used + 1; end if; ----Copy the array into the buffer. To_Raw (Display.Output.Data (Display.Output.Used + Request_Size + 1 .. Last_Byte), D); Display.Output.Used := Last_Byte; return; end if; ----This request will not fit in the buffer space available; flush the buffer. Internal_X_Flush_Display (Display); ----If this request will fit into the buffer now (usual case) then just do that. if Total_Size <= S_Long (Display.Output.Data'Last - Request_Size) then ----Calculate the last byte that will be used. Then calculate the number -- of spaces that remain in the buffer for new array elements. Last_Byte := Request_Size + X_Raw_Data_Index (Total_Size); Incr := S_Long (Display.Output.Data'Last - Last_Byte / Original_Size); Incr := Min (Max_Spaces - D'Length, Incr); Spaces_Left := Incr; ----If there are no more spaces left then shove the request into the buffer. if Incr = 0 then To_Raw (Display.Output.Data (1 .. Request_Size), Req); Reservation := 0; else Reservation := Display.Output.Used + 1; end if; ----Copy the array into the buffer. To_Raw (Display.Output.Data (Request_Size + 1 .. Last_Byte), D); Display.Output.Used := Last_Byte; return; end if; ----The caller is shipping something very large. Put out the request and we -- will follow it with the array elements. Reservation := 0; Spaces_Left := 0; To_Raw (Display.Output.Data (1 .. Request_Size), Req); ----Put out the array elements a few at a time. Next := S_Long (D'First); Incr := S_Long ((Display.Input.Data'Last - Request_Size) / Original_Size); Last_Byte := Original_Size * X_Raw_Data_Index (Incr); ----Put out the first few elements. To_Raw (Display.Output.Data (Request_Size + 1 .. Last_Byte), D (Index (Next) .. Index (Next + Incr - 1))); Display.Output.Used := Last_Byte; Internal_X_Flush_Display (Display); Next := Next + Incr; ----Prepare to put out full size chunks. Incr := S_Long (Display.Input.Data'Last / Original_Size); Last_Byte := Original_Size * X_Raw_Data_Index (Incr); ----First we write them as complete Display.Input.Data buffer-fulls at a time. while S_Long (D'Last) - Next >= Incr loop To_Raw (Display.Output.Data (1 .. Last_Byte), D (Index (Next) .. Index (Next + Incr - 1))); Display.Output.Used := Last_Byte; Internal_X_Flush_Display (Display); Next := Next + Incr; end loop; ----Finally we write whatever is left to write. if Next <= S_Long (D'Last) then Last_Byte := Original_Size * X_Raw_Data_Index (S_Long (D'Last) - Next + 1); To_Raw (Display.Output.Data (1 .. Last_Byte), D (Index (Next) .. D'Last)); Display.Output.Used := Last_Byte; end if; end Reserve_Request_Large_1d; --\f procedure Place_Reserved_Request (Display : X_Display; Req : Request; Reservation : X_Raw_Data_Index) is ------------------------------------------------------------------------------ -- For X_Request's only. Do not use this for ordinary private types. -- -- If you get a Constraint_Error when elaborating this generic then you have -- tried to instantiate it with a type whose 'Size is not N*32. -- -- Put data into a reserved place within the buffer going to a particular -- display. All X requests are always a multiple of 32 bits (4 bytes) in -- length. Display.Last_Req is not set; that is up to the caller. -- Request - this is the type of data that needs to be sent -- To_Raw - converts the data to X_Raw_Data -- Request_Size - all X protocol requests are 4*N bytes long, this value -- corresponds to the number of X_Raw_Data items required -- to represent the Request -- Multiple_Of_32 - causes Constraint_Error if Request is of an inappropriate -- 'Size -- Display - display to receive the request -- Req - the X_Request to send ------------------------------------------------------------------------------ Last_Byte : X_Raw_Data_Index; begin ----If this fails then the previous request left the buffer on a non-word -- boundary. That would mean that we are harboring a bug somewhere. --/ if DEBUG then if Request_Size rem 4 /= 0 then raise X_Library_Confusion; elsif Display.Output.Used rem 4 /= 0 then raise X_Library_Confusion; end if; --/ end if; ----Put the data into the buffer. To_Raw (Display.Output.Data (Reservation .. Reservation + Request_Size - 1), Req); begin Display.Request := Display.Request + 1; exception when Constraint_Error => Display.Request := (Display.Request - 16#7F00_0000#) + 1; Display.Last_Request_Read := Display.Last_Request_Read - 16#7F00_0000#; end; end Place_Reserved_Request; --\f end Xlbmp_Put;