From 8f90db34ff7e67620469e28adac7d5c426a90099 Mon Sep 17 00:00:00 2001
From: Per Hedbor <ph@opera.com>
Date: Thu, 1 Jan 1998 01:30:43 +0100
Subject: [PATCH] Fixed colorhandling and such

Rev: lib/modules/Protocols.pmod/X.pmod/Requests.pmod:1.6
Rev: lib/modules/Protocols.pmod/X.pmod/Types.pmod:1.7
Rev: lib/modules/Protocols.pmod/X.pmod/Xlib.pmod:1.7
---
 .../Protocols.pmod/X.pmod/Requests.pmod       | 80 +++++++++++++++
 lib/modules/Protocols.pmod/X.pmod/Types.pmod  | 99 ++++++++++++++-----
 lib/modules/Protocols.pmod/X.pmod/Xlib.pmod   | 76 ++++++++------
 3 files changed, 204 insertions(+), 51 deletions(-)

diff --git a/lib/modules/Protocols.pmod/X.pmod/Requests.pmod b/lib/modules/Protocols.pmod/X.pmod/Requests.pmod
index f69be39696..633f855ff6 100644
--- a/lib/modules/Protocols.pmod/X.pmod/Requests.pmod
+++ b/lib/modules/Protocols.pmod/X.pmod/Requests.pmod
@@ -271,3 +271,83 @@ class PolyFillRectangle
 				 rectangles->to_string()));
   }
 }
+
+class PutImage
+{
+  inherit request;
+  constant type = 72;
+  int drawable;
+  int gc;
+
+  int depth;
+  int width;
+  int height;
+  int dst_x;
+  int dst_y;
+  int left_pad = 0;
+  int format = 2; // Bitmap XYPixmap ZPixmap
+  
+  string data;
+
+  string to_string()
+  {
+  string pad="";
+    while(((strlen(data)+strlen(pad))%4)) pad += "\0";
+    pad =  build_request(sprintf("%4c" "%4c"
+				 "%2c" "%2c"
+				 "%2c" "%2c"
+				 "%c" "%c" "\0\0"
+				 "%s%s",
+				 drawable, gc,
+				 width, height,
+				 dst_x, dst_y, left_pad, depth,
+				 data,pad), format);
+    data=0;
+    return pad;
+  }
+  
+}
+
+class CreateColormap
+{
+  inherit request;
+  constant type = 78;
+
+  int cid;
+  int alloc;
+  
+  int window;
+  int visual;
+
+  string to_string()
+  {
+    return build_request(sprintf("%4c%4c%4c", cid, window, visual), alloc);
+  }
+}
+
+class AllocColor
+{
+  inherit request;
+  constant type = 84;
+  
+  int red, green, blue;
+  int colormap;
+  
+  string to_string()
+  {
+    return build_request(sprintf("%4c%2c%2c%2c\0\0", 
+				 colormap, red, green, blue ));
+  }
+
+  mixed handle_reply(mapping reply)
+  {
+    int pixel, r, g, b;
+    sscanf(reply->rest, "%2c%2c%2c%*2c%4c", r, g, b, pixel);
+    return ([ "pixel":pixel, "red":r, "green":g, "blue":b ]);
+  }
+
+  mixed handle_error(string reply)
+  {
+    return 0;
+  }
+}
diff --git a/lib/modules/Protocols.pmod/X.pmod/Types.pmod b/lib/modules/Protocols.pmod/X.pmod/Types.pmod
index a32d5379ec..c522514d7c 100644
--- a/lib/modules/Protocols.pmod/X.pmod/Types.pmod
+++ b/lib/modules/Protocols.pmod/X.pmod/Types.pmod
@@ -104,6 +104,35 @@ class Point
   }
 }
 
+class Colormap
+{
+  inherit XResource;
+  object visual;
+  mapping alloced = ([]);
+
+  int AllocColor(int r, int g, int b)
+  {
+    if(alloced[sprintf("%2c%2c%2c", r, g, b)])
+      return alloced[sprintf("%2c%2c%2c", r, g, b)];
+    object req = Requests.AllocColor();
+    req->colormap = id;
+    req->red = r;
+    req->green = g;
+    req->blue = b;
+    return (alloced[sprintf("%2c%2c%2c", r, g, b)]=
+	    display->blocking_request( req ));
+  }
+
+
+  void create(object disp, int i, object vis)
+  {
+    display = disp;
+    id = i;
+    visual = vis;
+  }
+}
+
+
 class Drawable
 {
   inherit XResource;
@@ -174,12 +203,27 @@ class Drawable
   {
     display->send_request(DrawLine_req(gc->id, coordMode, points));
   }
+
+  void PutImage(object gc, int depth,
+		int tx, int ty, int width, int height, string data)
+  {
+    object r = Requests.PutImage();
+    r->drawable = id;
+    r->gc = gc->id;
+    r->depth = depth;
+    r->dst_x = tx;
+    r->dst_y = ty;
+    r->width = width;
+    r->height = height;
+    r->data = data;
+    display->send_request(r);
+  }
 }
-  
+
 class Window
 {
   inherit Drawable;
-  object visual;
+  object visual, colortable, parent;
   int currentInputMask;
 
   mapping(string:function) event_callbacks = ([ ]);
@@ -259,12 +303,11 @@ class Window
 	 thai .. korean .. hangul .. */
     }
   } 
-
-  // FIXME! Should use some sort of (global..) db.
-  mapping compose_patterns = decode_value(Stdio.read_bytes("db/compose.db"));
+  mapping compose_patterns;
   string compose_state = "";
   string LookupKeysym( int keysym )
   {
+    if(!compose_patterns) compose_patterns =  display->compose_patterns;
     switch(keysym)
     {
      case XK_A..XK_Z: 
@@ -334,10 +377,10 @@ class Window
   }
   
   object CreateWindow_req(int x, int y, int width, int height,
-			  int border_width)
+			  int border_width, int depth, object visual)
   {
     object req = Requests.CreateWindow();
-    req->depth = 0;  /* CopyFromParent */
+    req->depth = depth;  /* CopyFromParent */
     req->wid = display->alloc_id();
     req->parent = id;
     req->x = x;
@@ -346,7 +389,7 @@ class Window
     req->height = height;
     req->borderWidth = border_width;
     req->c_class = 0 ;  /* CopyFromParent */
-    req->visual = 0;    /* CopyFromParent */
+    req->visual = visual && visual->id;
     return req;
   }
 
@@ -355,20 +398,33 @@ class Window
     return object_program(this_object())(@args);
   }
 
-  /* FIXME: Supports only visual CopyFromParent */
+  object CreateColormap(object visual, int|void alloc)
+  {
+    object req = Requests.CreateColormap();
+    req->cid = display->alloc_id();
+    req->alloc = alloc;
+    req->visual = visual->id;
+    req->window = id;
+    display->send_request(req);
+    return Colormap(display, req->cid, visual);
+  }
+
   object CreateWindow(int x, int y, int width, int height,
-		      int border_width, mapping attributes)
+		      int border_width, mapping attributes,
+		      object|void visual, int|void depth,
+		      int|void c_class)
   {
     object req = CreateWindow_req(x, y, width, height,
-				  border_width);
+				  border_width,depth,visual);
+
     if (attributes)
       req->attributes = attributes;
-    display->send_request(req);
-    
+
+
     // object w = Window(display, req->wid);
-    object w = new(display, req->wid);
-    
-    w->visual = visual;
+    display->send_request(req);
+    object w = new(display, req->wid, visual, this_object());
+    w->colortable = req->attributes->Colormap;
     w->currentInputMask = req->attributes->EventMask;
     return w;
   }
@@ -378,14 +434,14 @@ class Window
 			    int border, int background)
   {
     object req = CreateWindow_req(x, y, width, height,
-				  border_width);
+				  border_width,0,0);
     req->attributes->BackPixel = background;
     req->attributes->BorderPixel = border;
 
     display->send_request(req);
     
     // object w = Window(display, req->wid);
-    object w = new(display, req->wid);
+    object w = new(display, req->wid, 0, this_object());
     
     w->visual = visual;
     w->currentInputMask = 0;
@@ -481,16 +537,13 @@ class Window
   void create(mixed ... args)
   {
     ::create( @args );
+    if(sizeof(args)>2 && objectp(args[2]))  visual = args[2];
+    if(sizeof(args)>3 && objectp(args[3]))  parent = args[3];
     set_event_callback("_KeyPress", handle_keys);
     set_event_callback("_KeyRelease", handle_keys);
   }
 }
 
-class Colormap
-{
-  inherit XResource;
-}
-
 class RootWindow
 {
   inherit Window;
diff --git a/lib/modules/Protocols.pmod/X.pmod/Xlib.pmod b/lib/modules/Protocols.pmod/X.pmod/Xlib.pmod
index 0ef19f0ebd..59ccbdd350 100644
--- a/lib/modules/Protocols.pmod/X.pmod/Xlib.pmod
+++ b/lib/modules/Protocols.pmod/X.pmod/Xlib.pmod
@@ -55,7 +55,7 @@ class async_request
     callback = f;
   }
 
-  void handle_reply(int success, string reply)
+  void handle_reply( int success, string reply)
   {
     callback(success, (success ? req->handle_reply : req->handle_error)(reply));
   }
@@ -106,6 +106,9 @@ class Display
   
   inherit Stdio.File;
   inherit id_manager;
+
+  // FIXME! Should use some sort of (global) db.
+  mapping compose_patterns = decode_value(Stdio.read_bytes("db/compose.db"));
   
   program Struct = my_struct.struct;
   
@@ -161,29 +164,33 @@ class Display
   {
     int written = write(buffer);
     if (written <= 0)
-      {
-	if (io_error_handler)
-	  io_error_handler(this_object());
-	close();
-      }
+    {
+      if (io_error_handler)
+	io_error_handler(this_object());
+      close();
+    }
     else
-      {
-	buffer = buffer[written..];
-	if (!strlen(buffer))
-	  set_write_callback(0);
-      }
+    {
+      buffer = buffer[written..];
+      if (!strlen(buffer))
+	set_write_callback(0);
+    }
   }
 
   void send(string data)
   {
-//     werror(sprintf("Xlib.Display->send: '%s'\n", data));
+    int ob = strlen(buffer);
     buffer += data;
-    if (strlen(buffer))
+    if (!ob && strlen(buffer))
+    {
       set_write_callback(write_callback);
+      write_callback( );
+    }
   }
 
   int flush()
   { /* FIXME: Not thread-safe */
+//     trace(5);
     set_blocking();
     int result = 0;
     mixed e = catch {
@@ -193,7 +200,7 @@ class Display
 	  break;
 	buffer = buffer[written..];
       
-	if (strlen(buffer)) 
+	if (strlen(buffer))
 	  break;
 	set_write_callback(0);
 	result = 1;
@@ -203,6 +210,7 @@ class Display
     if (e)
       throw(e);
     // werror(sprintf("flush: result = %d\n", result));
+//     trace(0);
     return result;
   }
   
@@ -310,7 +318,7 @@ class Display
 		int wid = struct->get_uint(4);
 		object r = Types.RootWindow(this_object(), wid);
 		int cm = struct->get_uint(4);
-		r->defaultColorMap = Types.Colormap(this_object(), cm);
+		r->defaultColorMap = Types.Colormap(this_object(), cm, 0);
 		r->whitePixel = struct->get_uint(4);
 		r->blackPixel = struct->get_uint(4);
 		r->currentInputMask = struct->get_uint(4);
@@ -551,7 +559,7 @@ class Display
 	  if (handler)
 	    {
 	      m_delete(pending_requests, a[1]->sequenceNumber);
-	      handler->handle_reply(1, a[1]);
+	      handler->handle_reply(1, a[1] );
 	    }
 	  else if(reply_handler)
 	    reply_handler(this_object(), a[1]);
@@ -619,8 +627,20 @@ class Display
 
     string host = strlen(fields[0]) ? fields[0] : "localhost";
 
-    if (!connect(host, XPORT + (int)fields[1]))
-      return 0;
+    if(!strlen(fields[0]))
+    {
+      if(File::open("/tmp/.X11-pipe/X"+((int)fields[1]), "rw"))
+      {
+	werror("Using local transport\n");
+	host=0;
+      } else
+	werror("Failed to use local transport.\n");
+    }
+    if(host)
+      if (!connect(host, XPORT + (int)fields[1]))
+	return 0;
+
+    set_buffer( 65536 );
 
     /* Asynchronous connection */
     if (async)
@@ -681,9 +701,8 @@ class Display
     int done = 0;
 
     int n = send_request(req);
-    flush();
-    set_blocking();
-
+     flush();
+     set_blocking();
     mixed e = catch {
       while(!done)
 	{
@@ -697,14 +716,14 @@ class Display
 	      if ((a[0] == ACTION_REPLY)
 		  && (a[1]->sequenceNumber == n))
 		{
-		  result = req->handle_reply(1,a[1]);
+		  result = req->handle_reply(a[1]);
 		  done = 1;
 		  break;
 		}
 	      else if ((a[0] == ACTION_ERROR)
 		       && (a[1]->sequenceNumber == n))
 		{
-		  result = req->handle_error(1,a[1]);
+		  result = req->handle_error(a[1]);
 		  done = 1;
 		  break;
 		}
@@ -716,11 +735,12 @@ class Display
     set_nonblocking();
     if (e)
       throw(e);
-    if (pending_actions->size())
-      {
-	set_read_callback(0);
-	call_out(process_pending_actions, 0);
-      }
+    if (!pending_actions->is_empty())
+    {
+      set_read_callback(0);
+      call_out(process_pending_actions, 0);
+    } else
+      set_read_callback( read_callback );
     return result;
   }
   
-- 
GitLab