Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first public revision

  • Loading branch information...
commit 873610adc744d840d66d52684c157f3a3e38ebf6 0 parents
@NotFound authored
19 Guitor.winxhead
@@ -0,0 +1,19 @@
+// Guitor.winxhead
+
+// Declarations for Guitor
+
+$include "GuitorConstants.winxhead";
+
+namespace Guitor
+{
+
+class Display;
+class Event;
+
+class Controller;
+class TopLevelWindow;
+class ChildWindow;
+
+}
+
+// End
37 GuitorConstants.winxhead
@@ -0,0 +1,37 @@
+// GuitorConstants.winxhead
+
+// Declarations for Guitor
+// Xlib constants commonly used
+
+namespace Guitor
+{
+
+namespace Events
+{
+
+// Event selection masks
+const int KeyPressMask = 0x00000001;
+const int KeyReleaseMask = 0x00000002;
+const int ButtonPressMask = 0x00000004;
+const int ButtonReleaseMask = 0x00000008;
+const int EnterWindowMask = 0x00000010;
+const int LeaveWindowMask = 0x00000020;
+const int PointerMotionMask = 0x00000040;
+const int ExposureMask = 0x00008000;
+const int StructureNotifyMask = 0x00020000;
+// Event types
+const int KeyPress = 2;
+const int KeyRelease = 3;
+const int ButtonPress = 4;
+const int ButtonRelease = 5;
+const int MotionNotify = 6;
+const int Expose = 12;
+const int DestroyNotify = 17;
+const int ConfigureNotify = 22;
+const int ClientMessage = 33;
+
+}
+
+}
+
+// End
7 README
@@ -0,0 +1,7 @@
+Guitor (C) 2011 Julián Albo
+
+Guitor is a parrot module for building GUI using Xlib.
+
+Use the Makefile or seetup winxed
+
+Under development. Tested only with Linux amd64.
339 examples/boxes.winxed
@@ -0,0 +1,339 @@
+#! winxed
+
+// boxes: put boxes with text
+
+$load "Guitor.pbc";
+
+$include "Guitor.winxhead";
+
+using namespace Guitor;
+using namespace Guitor.Events;
+
+//**********************************************************************
+
+const int STEP = 4; // pixels
+
+class Boxes : TopLevelWindow
+{
+ var boxlist;
+ var activebox;
+ var width;
+ var height;
+ var x;
+ var y;
+ var x1;
+ var y1;
+ var pressed;
+ var numcolor;
+ function Boxes(controller)
+ {
+ self.boxlist = [];
+ self.activebox = -1;
+ self.x = 0;
+ self.y = 0;
+ self.x1 = 0;
+ self.y1 = 0;
+ self.pressed = false;
+ self.numcolor = 0;
+ self.width = 600;
+ self.height = 400;
+ self.TopLevelWindow(controller, "Boxes", 0, 0, 600, 400);
+
+ self.OnConfigure += function (event) { self.onConfigure(event); };
+ self.OnExpose += function (event) { self.onExpose(event); };
+ self.OnKeyPress += function (event) { self.onKeyPress(event); };
+ self.OnButtonPress += function (event) { self.onButtonPress(event); };
+ self.OnButtonRelease += function (event) { self.onButtonRelease(event); };
+ self.OnMotion += function (event) { self.onMotion(event); };
+ self.OnClientMessage += function (event) { self.onClientMessage(event); };
+ self.OnDestroy += function (event)
+ {
+ var controller = self.controller;
+ controller.unregister(self);
+ controller.Quit();
+ };
+ }
+ function activate(box)
+ {
+ var boxlist = self.boxlist;
+ for (int i = 0, n = elements(boxlist); i < n; ++i)
+ if (boxlist[i] === box) {
+ self.activebox =: i;
+ box.RaiseWindow();
+ break;
+ }
+ }
+
+ function onConfigure(event)
+ {
+ self.width =: int(event.width());
+ self.height =: int(event.height());
+ }
+ function onExpose(event)
+ {
+ }
+ function onKeyPress(event)
+ {
+ var display = self.display;
+ var boxlist = self.boxlist;
+ int active = self.activebox;
+ int code = event.keycode();
+
+ string key = display.KeysymToString(display.KeycodeToKeysym(code));
+ switch (key) {
+ case "Escape":
+ self.Destroy();
+ break;
+ case "BackSpace":
+ if (active >= 0)
+ {
+ var boxlist = self.boxlist;
+ var box = boxlist[active];
+ box.Destroy();
+ delete boxlist[active];
+ if (active >= elements(boxlist))
+ --active;
+ self.activebox =: active;
+ }
+ break;
+ case 'Up':
+ if (active >= 0) {
+ var box = boxlist[active];
+ box.MoveWindow(box.posx, box.posy - STEP);
+ }
+ break;
+ case 'Down':
+ if (active >= 0) {
+ var box = boxlist[active];
+ box.MoveWindow(box.posx, box.posy + STEP);
+ }
+ break;
+ case 'Left':
+ if (active >= 0) {
+ var box = boxlist[active];
+ box.MoveWindow(box.posx - STEP, box.posy);
+ }
+ break;
+ case 'Right':
+ if (active >= 0) {
+ var box = boxlist[active];
+ box.MoveWindow(box.posx + STEP, box.posy);
+ }
+ break;
+ case 'Home':
+ if (active >= 0) {
+ var box = boxlist[active];
+ box.MoveWindow(0, box.posy);
+ }
+ break;
+ case 'End':
+ if (active >= 0) {
+ var box = boxlist[active];
+ box.MoveWindow(self.width - box.width, box.posy);
+ }
+ break;
+ case 'Prior':
+ if (active >= 0) {
+ var box = boxlist[active];
+ box.MoveWindow(box.posx, 0);
+ }
+ break;
+ case 'Next':
+ if (active >= 0) {
+ var box = boxlist[active];
+ box.MoveWindow(box.posx, self.height - box.height);
+ }
+ break;
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ self.numcolor =: int(key);
+ break;
+ }
+ }
+ function onButtonPress(event)
+ {
+ self.pressed =: true;
+ int x = event.x();
+ int y = event.y();
+ self.x =: x;
+ self.y =: y;
+ self.x1 =: x;
+ self.y1 =: y;
+ self.SetFunction(0xa);
+ self.SetLineAttributes(0, 1, 0, 0);
+ self.SetSubwindowMode(1);
+ }
+ function onButtonRelease(event)
+ {
+ self.pressed =: false;
+ int x = self.x;
+ int y = self.y;
+ int x1 = self.x1;
+ int y1 = self.y1;
+ self.rectangle(x, y, x1, y1);
+ int x2 = event.x();
+ int y2 = event.y();
+ int width, height;
+ if (x2 > x)
+ width = x2 - x;
+ else {
+ width = x - x2;
+ x = x2;
+ }
+ if (y2 > y)
+ height = y2 - y;
+ else {
+ height = y - y2;
+ y = y2;
+ }
+ if (width == 0 || height == 0)
+ return;
+ var boxlist = self.boxlist;
+ string color;
+ switch (self.numcolor) {
+ case 0: color = "yellow"; break;
+ case 1: color = "red"; break;
+ case 2: color = "blue"; break;
+ case 3: color = "light steel blue"; break;
+ case 4: color = "orange"; break;
+ case 5: color = "green"; break;
+ case 6: color = "maroon"; break;
+ case 7: color = "aquamarine"; break;
+ case 8: color = "coral"; break;
+ default: color = "violet";
+ }
+ var box = new Box(self, x, y, width, height,
+ { "background_color" : self.display.ParseColor(color) } );
+ box.Map();
+ int active = elements(boxlist);
+ push(boxlist, box);
+ self.activebox =: active;
+ self.SetFunction(0x3);
+ self.SetLineAttributes(0, 0, 0, 0);
+ self.SetSubwindowMode(0);
+ }
+ function onMotion(event)
+ {
+ if (self.pressed) {
+ int x = self.x;
+ int y = self.y;
+ int x1 = self.x1;
+ int y1 = self.y1;
+ int x2 = event.x();
+ int y2 = event.y();
+ if (x != x1 && y != y1)
+ self.rectangle(x, y, x1, y1);
+ self.rectangle(x, y, x2, y2);
+ self.x1 =: x2;
+ self.y1 =: y2;
+ }
+ }
+ function rectangle(int x1, int y1, int x2, int y2)
+ {
+ int x = x1;
+ int y = y1;
+ int width = x2 - x;
+ int height = y2 - y;
+ if (width && height) {
+ if (x > x2) {
+ x = x2;
+ width = -width;
+ }
+ if (y > y2) {
+ y = y2;
+ height = -height;
+ }
+ self.DrawRectangle(x, y, width, height);
+ }
+ }
+ function onClientMessage(event)
+ {
+ self.Destroy();
+ }
+}
+
+class Box : ChildWindow
+{
+ var moving;
+ var posx;
+ var posy;
+ var width;
+ var height;
+ var movex;
+ var movey;
+ function Box(parent, int x, int y, int width, int height, style [optional])
+ {
+ self.ChildWindow(parent, x, y, width, height, style);
+ self.moving = false;
+ self.posx = x;
+ self.posy = y;
+ self.width = width;
+ self.height = height;
+ self.movex = 0;
+ self.movey = 0;
+ self.OnConfigure += function(event)
+ {
+ self.width =: int(event.width());
+ self.height =: int(event.height());
+ self.posx =: int(event.x());
+ self.posy =: int(event.y());
+ };
+ self.OnExpose += function (event)
+ {
+ int width = self.width - 1;
+ int height = self.height - 1;
+ self.DrawLine(0, 0, width, 0);
+ self.DrawLine(0, height, width, height);
+ self.DrawLine(0, 0, 0, height);
+ self.DrawLine(width, 0, width, height);
+ };
+ self.OnButtonPress += function (event)
+ {
+ self.moving =: true;
+ self.movex =: int(event.x_root());
+ self.movey =: int(event.y_root());
+ parent.activate(self);
+ };
+ self.OnButtonRelease += function (event)
+ {
+ self.moving =: false;
+ };
+ self.OnMotion += function (event)
+ {
+ if (self.moving) {
+ int evx = event.x_root();
+ int evy = event.y_root();
+ int x = evx - self.movex;
+ int y = evy - self.movey;
+ if (x != 0 || y != 0) {
+ self.movex =: evx;
+ self.movey =: evy;
+ int childx = self.posx + x;
+ int childy = self.posy + y;
+ self.MoveWindow(childx, childy);
+ self.posx =: childx;
+ self.posy =: childy;
+ }
+ }
+ };
+ }
+}
+
+//**********************************************************************
+
+function main(args)
+{
+ var controller = new Controller();
+ controller.setDefaultFont("-*-liberation.mono-medium-r-*-*-*-120-*");
+
+ var boxes = new Boxes(controller);
+ boxes.SetWMProtocols(['WM_DELETE_WINDOW']);
+ boxes.Map();
+
+ controller.MainLoop();
+
+ say('End');
+ controller.Close();
+}
+
+// End.
439 examples/graph.winxed
@@ -0,0 +1,439 @@
+#! winxed
+
+// graph
+
+//**************************************************************
+
+$load "Guitor.pbc";
+
+$include "Guitor.winxhead";
+
+using namespace Guitor;
+using namespace Guitor.Events;
+
+//**************************************************************
+
+class Graph : TopLevelWindow
+{
+ var funcs;
+ var x0;
+ var x1;
+ var y0;
+ var y1;
+ var width;
+ var height;
+ var pressed;
+ var xp0;
+ var yp0;
+ var xp1;
+ var yp1;
+ function Graph(controller, string expr, funcs, float x0, float x1, float y0, float y1)
+ {
+ self.pressed = false;
+ self.funcs = funcs;
+ self.x0 = x0;
+ self.x1 = x1;
+ self.y0 = y0;
+ self.y1 = y1;
+ int width = 800;
+ int height = 600;
+ self.width = width;
+ self.height = height;
+
+ self.TopLevelWindow(controller, "graph - " + expr, 0, 0, width, height);
+ self.OnClientMessage += function (event) { self.onClientMessage(event); };
+ self.OnConfigure += function (event) { self.onConfigure(event); };
+ self.OnExpose += function (event) { self.onExpose(event); };
+ self.OnKeyPress += function (event) { self.onKeyPress(event); };
+ self.OnButtonPress += function (event) { self.onButtonPress(event); };
+ self.OnButtonRelease += function (event) { self.onButtonRelease(event); };
+ self.OnMotion += function (event) { self.onMotion(event); };
+ }
+ function drawfun(fun)
+ {
+ float x0 = self.x0;
+ float x1 = self.x1;
+ float y0 = self.y0;
+ float y1 = self.y1;
+ int width = self.width;
+ int height = self.height;
+ int prev = false;
+ int i0, j0;
+ for (int i = 0; i < width; ++i) {
+ try {
+ float x = x0 + (float(i) / width) * (x1 - x0);
+ float y = fun(x);
+ int j = height - 1 - (y - y0) / (y1 - y0) * height;
+ int current = true;
+ if (j < 0 || j >= height) {
+ current = false;
+ if (prev) {
+ j = j < 0 ? 0 : height - 1;
+ self.DrawLine(i0, j0, i, j);
+ }
+ }
+ else {
+ if (prev)
+ self.DrawLine(i0, j0, i, j);
+ else
+ self.DrawPoint(i, j);
+ }
+ prev = current;
+ i0 = i;
+ j0 = j;
+ }
+ catch () {
+ prev = false;
+ }
+ }
+ }
+ function onClientMessage(event)
+ {
+ self.Destroy();
+ }
+ function onConfigure(event)
+ {
+ self.width =: int(event.width());
+ self.height =: int(event.height());
+ }
+ function onExpose(event)
+ {
+ float x0 = self.x0;
+ float x1 = self.x1;
+ float y0 = self.y0;
+ float y1 = self.y1;
+ int width = self.width;
+ int height = self.height;
+ try {
+ int j = height + y0 * height / (y1 - y0);
+ if (j > 0 && j < height)
+ self.DrawLine(0, j, width, j);
+ }
+ catch () { }
+ try {
+ int i = -x0 * width / (x1 - x0);
+ if (i > 0 && i < width)
+ self.DrawLine(i, 0, i, height);
+ }
+ catch () { }
+
+ var funcs = self.funcs;
+ if (elements(funcs) == 1)
+ self.drawfun(funcs[0]);
+ else {
+ string colors[] = [ "black", "red", "blue", "green" ];
+ int ncolors = elements(colors);
+ int i = 0;
+ for (var fun in self.funcs) {
+ self.SetForeground(colors[i]);
+ i = (i + 1) % ncolors;
+ self.drawfun(fun);
+ }
+ self.SetForeground(colors[0]);
+ }
+ }
+ function onKeyPress(event)
+ {
+ var display = self.display;
+ float x0 = self.x0;
+ float x1 = self.x1;
+ float y0 = self.y0;
+ float y1 = self.y1;
+ float r;
+ int code = event.keycode();
+ string key = display.KeysymToString(display.KeycodeToKeysym(code));
+ switch (key) {
+ case "Escape":
+ self.Destroy();
+ break;
+ case "plus":
+ r = (x1 - x0) / 4;
+ x0 += r;
+ x1 -= r;
+ self.x0 =: x0;
+ self.x1 =: x1;
+ r = (y1 - y0) / 4;
+ y0 += r;
+ y1 -= r;
+ self.y0 =: y0;
+ self.y1 =: y1;
+ self.ClearArea(0, 0, self.width, self.height, 1);
+ break;
+ case "minus":
+ r = (x1 - x0) / 2;
+ x0 -= r;
+ x1 += r;
+ self.x0 =: x0;
+ self.x1 =: x1;
+ r = (y1 - y0) / 2;
+ y0 -= r;
+ y1 += r;
+ self.y0 =: y0;
+ self.y1 =: y1;
+ self.ClearArea(0, 0, self.width, self.height, 1);
+ break;
+ case "Left":
+ self.movehor(-4);
+ break;
+ case "Right":
+ self.movehor(4);
+ break;
+ case "Up":
+ self.movever(4);
+ break;
+ case "Down":
+ self.movever(-4);
+ break;
+ }
+ }
+ function onButtonPress(event)
+ {
+ int button = event.button();
+ switch (button) {
+ case 1:
+ case 3:
+ break;
+ case 4:
+ self.movever(4);
+ return;
+ case 5:
+ self.movever(-4);
+ return;
+ default:
+ return;
+ }
+ self.pressed =: button;
+ int x = event.x();
+ int y = event.y();
+ self.xp0 = x;
+ self.yp0 = y;
+ self.xp1 = x;
+ self.yp1 = y;
+ self.SetFunction(0xa);
+ self.SetLineAttributes(0, 1, 0, 0);
+ self.SetSubwindowMode(1);
+ }
+ function onButtonRelease(event)
+ {
+ int button = self.pressed;
+ if (! button)
+ return;
+ self.pressed =: false;
+ int xp0 = self.xp0;
+ int yp0 = self.yp0;
+ int nxp1 = self.xp1;
+ int nyp1 = self.yp1;
+ self.rectangle(xp0, yp0, nxp1, nyp1);
+ self.SetFunction(0x3);
+ self.SetLineAttributes(0, 0, 0, 0);
+ self.SetSubwindowMode(0);
+ int nxp0 = xp0;
+ if (nxp0 > nxp1) {
+ nxp0 = nxp1;
+ nxp1 = xp0;
+ }
+ int nyp0 = yp0;
+ if (nyp0 > nyp1) {
+ nyp0 = nyp1;
+ nyp1 = yp0;
+ }
+ float x0 = self.x0;
+ float x1 = self.x1;
+ float y0 = self.y0;
+ float y1 = self.y1;
+ int width = self.width;
+ int height = self.height;
+ if (nxp0 == nxp1 || nyp0 == nyp1) {
+ int i = self.xp1;
+ int j = self.yp1;
+ float x = x0 + (float(i) / width) * (x1 - x0);
+ float y = y0 + (float(height - j) / height) * (y1 - y0);
+ self.SetForeground("white");
+ self.FillRectangle(0, 0, 280, 36);
+ self.SetForeground("black");
+ self.DrawString(0, 16, "x: " + string(x));
+ self.DrawString(0, 32, "y: " + string(y));
+ return;
+ }
+ float xx0, xx1, yy0, yy1;
+ xx0 = x0 + (nxp0 / width) * (x1 - x0);
+ xx1 = x0 + (nxp1 / width) * (x1 - x0);
+ float yy = height - nyp0;
+ yy1 = y0 + (yy / height) * (y1 - y0);
+ yy = height - nyp1;
+ yy0 = y0 + (yy / height) * (y1 - y0);
+ switch (button) {
+ case 1:
+ break;
+ case 3:
+ var t0 = x0 + (x0 - xx0) * (x1 - x0) / (xx1 - xx0);
+ var t1 = x0 + (x1 - xx0) * (x1 - x0) / (xx1 - xx0);
+ xx0 = t0;
+ xx1 = t1;
+ t0 = y0 + (y0 - yy0) * (y1 - y0) / (yy1 - yy0);
+ t1 = y0 + (y1 - yy0) * (y1 - y0) / (yy1 - yy0);
+ yy0 = t0;
+ yy1 = t1;
+ break;
+ default:
+ return;
+ }
+ self.x0 =: xx0;
+ self.x1 =: xx1;
+ self.y0 =: yy0;
+ self.y1 =: yy1;
+ self.ClearArea(0, 0, width, height, 1);
+ }
+ function onMotion(event)
+ {
+ if (self.pressed) {
+ int x = self.xp0;
+ int y = self.yp0;
+ int x0 = self.xp1;
+ int y0 = self.yp1;
+ int x1 = event.x();
+ int y1 = event.y();
+ if (x != x0 && y != y0)
+ self.rectangle(x, y, x0, y0);
+ self.rectangle(x, y, x1, y1);
+ self.xp1 =: x1;
+ self.yp1 =: y1;
+ }
+ }
+ function movehor(int move)
+ {
+ int width = self.width;
+ float despl = (self.x1 - self.x0) / width * move;
+ self.x0 += despl;
+ self.x1 += despl;
+ self.ClearArea(0, 0, width, self.height, 1);
+ }
+ function movever(int move)
+ {
+ float despl = (self.y1 - self.y0) / self.width * move;
+ self.y1 += despl;
+ self.y0 += despl;
+ self.ClearArea(0, 0, self.width, self.height, 1);
+ }
+ function rectangle(int x0, int y0, int x1, int y1)
+ {
+ int x = x0;
+ int y = y0;
+ int width = x1 - x;
+ int height = y1 - y;
+ if (width && height) {
+ if (x > x1) {
+ x = x1;
+ width = -width;
+ }
+ if (y > y1) {
+ y = y1;
+ height = -height;
+ }
+ self.DrawRectangle(x, y, width, height);
+ }
+ }
+}
+
+//**************************************************************
+
+function rangey(fun, float x0, float x1)
+{
+ float y0 = 1.e100;
+ float y1 = -1.e100;
+ float step = (x1 - x0) / 800;
+ for (float x = x0; x <= x1; x += step) {
+ try {
+ float y = fun(x);
+ if (y < y0)
+ y0 = y;
+ if (y > y1)
+ y1 = y;
+ }
+ catch ()
+ {
+ }
+ }
+ return y0, y1;
+}
+
+//**************************************************************
+
+function compile(string expr)
+{
+ expr = "function evalexpr(float x) {\n return (" + expr + "); }\n";
+ load_language("winxed");
+ var compiler = compreg("winxed");
+ if (compiler == null)
+ throw "Can't get winxed compiler";
+ var code = compiler.compile(expr);
+ var fun = code[0];
+ return fun;
+}
+
+function main [main](args)
+{
+ int nargs = elements(args);
+ if (nargs < 2) {
+ cry("usage: graph [ --range x0,x1[y0,y1] ] function [ more functions ]");
+ exit(1);
+ }
+
+ int iarg = 1;
+ float x0 = -10, x1 = 10, y0 = -10, y1 = 10;
+ if (args[iarg] == "--range") {
+ ++iarg;
+ var values = split(",", args[iarg]);
+ switch (elements(values)) {
+ case 4:
+ y0 = values[2];
+ y1 = values[3];
+ case 2:
+ x0 = values[0];
+ x1 = values[1];
+ break;
+ default:
+ cry("Invalid range");
+ exit(1);
+ }
+ ++iarg;
+ }
+
+ string expr = "";
+ var funcs = [];
+ for (; iarg < nargs; ++iarg) {
+ string newexpr = args[iarg];
+ expr = expr + " | " + newexpr;
+ try {
+ var fun = compile(newexpr);
+ push(funcs, fun);
+ }
+ catch (e) {
+ cry("error compiling function: ", e["message"]);
+ exit(1);
+ }
+ }
+ if (elements(funcs) == 0) {
+ cry("usage: graph [ --range x0,x1[y0,y1] ] function [ more functions ]");
+ exit(1);
+ }
+
+ var display = new Display();
+ var controller = new Controller(display);
+ var graph = new Graph(controller, expr, funcs, x0, x1, y0, y1);
+ int loop = true;
+ display.SetWMProtocols(graph, ['WM_DELETE_WINDOW']);
+ graph.OnDestroy += function (event) {
+ loop = false;
+ };
+
+ graph.Map();
+ var event = new Event();
+ while (loop) {
+ display.NextEvent(event);
+ controller.handleEvent(event);
+ }
+ display.Close();
+}
+
+// End
276 examples/pizarra.winxed
@@ -0,0 +1,276 @@
+#! winxed
+
+// pizarra: a simple drawing tool using WinxedXlib module
+
+
+$load "Guitor.pbc";
+
+$include "Guitor.winxhead";
+
+using namespace Guitor;
+using namespace Guitor.Events;
+
+//**********************************************************************
+
+function evhandler(object, string methodname)
+{
+ var method = find_method(object, methodname);
+ return function (event) { object.*method(event); };
+}
+
+//**********************************************************************
+
+class ColorSelector : ChildWindow
+{
+ var pizarra;
+ var colors;
+ const int WIDTH = 50, HEIGHT = 82;
+ function ColorSelector(pizarra, int x, int y)
+ {
+ self.pizarra = pizarra;
+ string colors[] = [
+ "black", "white", "grey",
+ "red", "green", "blue",
+ "yellow", "pink", "orange",
+ "violet", "maroon", "aquamarine",
+ "coral", "lime green", "light steel blue"
+ ];
+ self.colors = colors;
+ self.ChildWindow(pizarra, x, y, WIDTH + 1, HEIGHT + 1);
+ self.OnExpose += evhandler(self, "onExpose");
+ self.OnButtonPress += evhandler(self, "onButtonPress");
+ self.Map();
+ }
+ function onExpose(event)
+ {
+ self.SetForeground("black");
+ self.DrawLine( 0, 0, WIDTH, 0);
+ self.DrawLine(WIDTH, 0, WIDTH, HEIGHT);
+ self.DrawLine(WIDTH, HEIGHT, 0, HEIGHT);
+ self.DrawLine( 0, HEIGHT, 0, 0);
+ var colors = self.colors;
+ for (int i = 0; i < 3; ++i)
+ for (int j = 0; j < 5; ++j) {
+ self.SetForeground("black");
+ self.DrawRectangle( 2 + i * 16, 2 + j * 16, 14, 14);
+ string color = colors[i * 3 + j];
+ self.SetForeground(color);
+ self.FillRectangle( 3 + i * 16, 3 + j * 16, 13, 13);
+ }
+ }
+ function onButtonPress(event)
+ {
+ int x = event.x();
+ int y = event.y();
+ x = x / 16;
+ y = y / 16;
+ if (x >= 0 || x < 3 || y >= 0 || y < 5) {
+ var colors = self.colors;
+ string color = colors[x * 3 + y];
+ self.pizarra.setcolor(color);
+ }
+ self.Destroy();
+ }
+}
+
+//**********************************************************************
+
+class Line
+{
+ var colorspec;
+ var xcoord;
+ var ycoord;
+ function Line(string colorspec)
+ {
+ self.colorspec = colorspec;
+ int x[];
+ int y[];
+ self.xcoord = x;
+ self.ycoord = y;
+ }
+ function push(int x, int y)
+ {
+ push(self.xcoord, x);
+ push(self.ycoord, y);
+ }
+ function draw(drawable)
+ {
+ var x = self.xcoord;
+ var y = self.ycoord;
+ int n = elements(x) - 1;
+ drawable.SetForeground(self.colorspec);
+ if (n == 0)
+ drawable.DrawPoint(x[0], y[0]);
+ else
+ for (int i = 0; i < n; ++i)
+ drawable.DrawLine(x[i], y[i], x[i + 1], y[i + 1]);
+ }
+}
+
+//**********************************************************************
+
+class Pizarra : TopLevelWindow
+{
+ var listline;
+ var line;
+ var pressed;
+ var oldx;
+ var oldy;
+ var colorspec;
+ function Pizarra(controller)
+ {
+ self.listline = [];
+ string title = "pizarra";
+ self.TopLevelWindow(controller, title, 0, 0, 600, 400);
+ controller.created(self);
+ self.pressed = false;
+ self.oldx = 0;
+ self.oldy = 0;
+ self.colorspec = "black";
+
+ self.OnDestroy += function (event)
+ {
+ self.controller.destroyed(self);
+ };
+ self.OnConfigure += function (event) { self.onConfigure(event); };
+ self.OnExpose += function (event) { self.onExpose(event); };
+ self.OnKeyPress += function (event) { self.onKeyPress(event); };
+ self.OnButtonPress += function (event) { self.onButtonPress(event); };
+ self.OnButtonRelease += function (event) { self.onButtonRelease(event); };
+ self.OnMotion += function (event) { self.onMotion(event); };
+ self.OnClientMessage += function (event) { self.onClientMessage(event); };
+ }
+
+ function onConfigure(event)
+ {
+ __DEBUG__ && cry(__FUNCTION__,
+ " x: ", event.x(), " y: ", event.y(),
+ " width: ", event.width(), " height: ", event.height());
+ }
+ function onExpose(event)
+ {
+ for (var l in self.listline)
+ l.draw(self);
+ }
+ function onKeyPress(event)
+ {
+ int code = event.keycode();
+ var display = self.display;
+ string key = display.KeysymToString(display.KeycodeToKeysym(code));
+ switch (key) {
+ case "Escape":
+ self.Destroy();
+ break;
+ case "c":
+ int x = event.x();
+ int y = event.y();
+ self.opencolorsel(x, y);
+ break;
+ case "BackSpace":
+ self.pressed =: false;
+ if (self.line != null)
+ self.line = null;
+ if (elements(self.listline) > 0)
+ self.listline.pop();
+ //TODO else beep, or something.
+ self.ClearArea(0, 0, 0, 0, 1);
+ break;
+ default:
+ int sym = self.display.KeycodeToKeysym(code);
+ say('Key name: ', self.display.KeysymToString(sym));
+ }
+ }
+ function onButtonPress(event)
+ {
+ int button = event.button();
+ self.pressed = button;
+ int oldx = event.x();
+ int oldy = event.y();
+ self.oldx =: oldx;
+ self.oldy =: oldy;
+ }
+ function onButtonRelease(event)
+ {
+ self.pressed = false;
+ self.line = null;
+ }
+ function onMotion(event)
+ {
+ if (self.pressed) {
+ int x = event.x();
+ int y = event.y();
+ int oldx = self.oldx;
+ int oldy = self.oldy;
+ if (x != oldx || y != oldy) {
+ var line = self.line;
+ if (line == null) {
+ self.line = line = new Line(self.colorspec);
+ self.listline.push(line);
+ line.push(oldx, oldy);
+ }
+ line.push(x, y);
+ line.draw(self);
+ self.oldx =: x;
+ self.oldy =: y;
+ }
+ }
+ }
+ function onClientMessage(event)
+ {
+ say('Bye');
+ self.Destroy();
+ }
+
+ function opencolorsel(int x, int y)
+ {
+ var colorsel = new ColorSelector(self, x, y);
+ }
+ function setcolor(string spec)
+ {
+ self.colorspec = spec;
+ }
+}
+
+//**********************************************************************
+
+class MyController : Controller
+{
+ var counter;
+ function MyController()
+ {
+ self.Controller();
+ self.counter = 0;
+ }
+ function created(pizarra)
+ {
+ self.counter++;
+ }
+ function destroyed(pizarra)
+ {
+ var counter = self.counter;
+ if (--counter == 0)
+ self.Quit();
+ }
+}
+
+//**********************************************************************
+
+function main(args)
+{
+ int nargs = elements(args);
+ var controller = new MyController();
+
+ int n = (nargs < 2) ? 1 : nargs - 1;
+ for (int i = 0; i < n; ++i) {
+ var pizarra = new Pizarra(controller);
+ pizarra.SetWMProtocols(['WM_DELETE_WINDOW']);
+ pizarra.Map();
+ }
+
+ controller.MainLoop();
+
+ say('End');
+ controller.Close();
+}
+
+// End.
759 src/Guitor.winxed
@@ -0,0 +1,759 @@
+#! winxed
+
+// Guitor.winxed
+
+// Xlib module via parrot NCI.
+
+$include "GuitorConstants.winxhead";
+
+$load "GuitorNci.pbc";
+
+namespace Guitor
+{
+
+$include_const "datatypes.pasm";
+
+//**************************************************************
+// Internal helper functions
+//**************************************************************
+
+namespace Xlib__private
+{
+
+extern function str_to_cstring;
+extern function string_from_nci;
+extern function getfun;
+extern function geteventpad;
+extern function getanyview;
+extern function getstructureview;
+extern function getexposeview;
+extern function getmotionview;
+extern function getbuttonview;
+extern function getkeyview;
+extern function getxcolorview;
+extern function getatomview;
+extern function getview;
+
+extern function newAtomlist;
+
+} // namespace Xlib__private
+
+using namespace Xlib__private;
+using namespace Events;
+
+
+//**************************************************************
+// Display
+//**************************************************************
+
+class Display
+{
+ var xdisplay;
+ var default_font;
+
+ function Display(string displayname[optional])
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ var d;
+ if (displayname == null)
+ displayname = "";
+ d = str_to_cstring(displayname);
+ self.xdisplay = getfun("XOpenDisplay")(d);
+ getfun("setlocale")(0, str_to_cstring(""));
+ getfun("XSetLocaleModifiers")(str_to_cstring(""));
+ }
+ function Close()
+ {
+ __DEBUG__ && cry("Display.Close");
+ getfun("XCloseDisplay")(self.xdisplay);
+ self.xdisplay = null;
+ __DEBUG__ && cry("closed");
+ }
+ function DefaultScreen()
+ {
+ int scrnum = getfun("XDefaultScreen")(self.xdisplay);
+ return scrnum;
+ }
+ function DefaultDepth(int scrnum)
+ {
+ int depth = getfun("XDefaultDepth")(self.xdisplay, scrnum);
+ return depth;
+ }
+ function BlackPixel(int scrnum)
+ {
+ return getfun("XBlackPixel")(self.xdisplay, scrnum);
+ }
+ function WhitePixel(int scrnum)
+ {
+ return getfun("XWhitePixel")(self.xdisplay, scrnum);
+ }
+ function KeycodeToKeysym(int keycode)
+ {
+ return getfun("XKeycodeToKeysym")(self.xdisplay, keycode, 0);
+ }
+ function KeysymToKeycode(int keysym)
+ {
+ return getfun("XKeysymToKeycode")(self.xdisplay, keysym);
+ }
+ function StringToKeysym(string keystring)
+ {
+ return getfun("XStringToKeysym")(str_to_cstring(keystring));
+ }
+ function KeysymToString(int keysym)
+ {
+ var fn = getfun("XKeysymToString");
+ return string_from_nci(fn(keysym));
+ }
+ function LookupString(event)
+ {
+ const int BUFSIZE = 32;
+ var fun = getfun("XLookupString");
+ var buffer = new ["ByteBuffer"];
+ buffer =: BUFSIZE;
+ int len = fun(event.eventdata, buffer, BUFSIZE, null, null);
+ string str;
+ if (len > 0) {
+ buffer =: len;
+ str = buffer.get_string("utf8");
+ }
+ return str;
+ }
+ function InternAtom(string name, int only_if_exists[optional])
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ var pname = str_to_cstring(name);
+ int atom = getfun("XInternAtom")(self.xdisplay, pname, only_if_exists);
+ return atom;
+ }
+ function GetAtomName(int atom)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ var fn = dlfunc(getlib(), "XGetAtomName", "tpi");
+ string name = fn(self.xdisplay, atom);
+ return name;
+ }
+ function AtomlistFromStrings(var atomnames)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ int natoms = elements(atomnames);
+ var aux = newAtomlist(natoms);
+ var ast = getatomview();
+ for (int i = 0; i < natoms; ++i)
+ ast[aux, i, 0] = int(self.InternAtom(atomnames[i]));
+ return aux;
+ }
+ function DefaultGC()
+ {
+ var fn = getfun("XDefaultGC");
+ return fn(self.xdisplay, self.DefaultScreen());
+ }
+ function _RootWindow(int scrnum)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ return getfun("XRootWindow")(self.xdisplay, scrnum);
+ }
+ function RootWindow(int scrnum)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ var fn = getfun("XRootWindow");
+ var rootw = new Window;
+ rootw.display = self;
+ rootw.xdrawable = fn(self.xdisplay, scrnum);
+ return rootw;
+ }
+ function CreateSimpleWindow(var parent,
+ int x, int y, int width, int height,
+ int border_width, int border, int background)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ var fn = getfun("XCreateSimpleWindow");
+ var w = new Window;
+ w.display = self;
+ w.xdrawable = fn(self.xdisplay, parent.xdrawable,
+ x, y, width, height, border_width, border, background);
+ return w;
+ }
+ function CreateSimpleWindow(int x, int y, int width, int height)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ var fn = getfun("XCreateSimpleWindow");
+ var xw = fn(self.xdisplay, self._RootWindow(0), x, y, width, height,
+ 0, self.BlackPixel(0), self.WhitePixel(0));
+ return xw;
+ }
+ function CreateSimpleChildWindow(parent, x, y, width, height,
+ int border_width, int border_color, int background)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ var fn = getfun("XCreateSimpleWindow");
+ var xw = fn(self.xdisplay, parent.xdrawable, x, y, width, height,
+ border_width, border_color, background);
+ return xw;
+ }
+ function NextEvent(var event)
+ {
+ using namespace Events;
+ var fn = getfun("XNextEvent");
+ event._get(self.xdisplay, fn);
+ }
+ function SetWMProtocols(drawable, names)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ var atomlist = self.AtomlistFromStrings(names);
+ var fn = getfun("XSetWMProtocols");
+ fn(self.xdisplay, drawable.xdrawable, atomlist, elements(names));
+ }
+
+ function ParseColor(string spec)
+ {
+ var xdisplay = self.xdisplay;
+ var fn = getfun("XParseColor");
+ var colormap = getfun("XDefaultColormap")(xdisplay, 0);
+ var xcolorview = getxcolorview();
+ var xcolor = xcolorview.alloc();
+ int status = fn(xdisplay, colormap, str_to_cstring(spec), xcolor);
+ if (status) {
+ status = getfun("XAllocColor")(xdisplay, colormap, xcolor);
+ if (status) {
+ int pixel = xcolorview[xcolor, 0];
+ return pixel;
+ }
+ }
+ return null;
+ }
+ function setDefaultFont(string fontdesc)
+ {
+ var font = self.default_font;
+ if (font == null) {
+ var ptr = new ["StructView"]( [DATATYPE_STRUCT, 1, DATATYPE_PTR ] );
+ var p1 = ptr.alloc();
+ var p2 = ptr.alloc();
+ var p3 = ptr.alloc();
+ font = getfun("XCreateFontSet")(self.xdisplay,
+ str_to_cstring(fontdesc), p1, p2, p3);
+ if (font == null || ! font)
+ return false;
+ }
+ self.default_font = font;
+ return true;
+ }
+ function getDefaultFont()
+ {
+ var font = self.default_font;
+ if (font == null) {
+ self.setDefaultFont("-*-*-*-r-*-*-*-140-*");
+ font = self.default_font;
+ }
+ return font;
+ }
+}
+
+//**********************************************************************
+
+function DisplayName()
+{
+ var fn = getfun("XDisplayName");
+ return string_from_nci(fn(null));
+}
+
+function KeysymToString(int keysym)
+{
+ var fn = getfun("XKeysymToString");
+ return string_from_nci(fn(keysym));
+}
+
+function StringToKeysym(string keystring)
+{
+ var fn = getfun("XStringToKeysym");
+ var pkey = str_to_cstring(keystring);
+ int k = fn(pkey);
+ return k;
+}
+
+function OpenDisplay(string displayname[optional])
+{
+ return new Display(displayname);
+}
+
+//**************************************************************
+// Event
+//**************************************************************
+
+class Event
+{
+ var eventdata;
+ var anyview;
+ var evtype;
+ var evx;
+ var evy;
+ var evx_root;
+ var evy_root;
+ var evwidth;
+ var evheight;
+ var evkeycode;
+ var evbutton;
+ function Event()
+ {
+ self.eventdata = geteventpad().alloc();
+ self.anyview = getanyview();
+ self.evtype = 0;
+ self.evx = 0;
+ self.evy = 0;
+ self.evx_root = 0;
+ self.evy_root = 0;
+ self.evwidth = 0;
+ self.evheight = 0;
+ self.evkeycode = 0;
+ self.evbutton = 0;
+ }
+ function _get(xdisplay, fn)
+ {
+ var eventdata = self.eventdata;
+ fn(xdisplay, eventdata);
+ var view = self.anyview;
+ int type = view[self.eventdata, 0];
+ self.evtype =: type;
+ int x = 0, y = 0, x_root = 0, y_root = 0,
+ width = 0, height = 0,
+ keycode = 0, button = 0;
+ switch (type) {
+ case ConfigureNotify:
+ view = getstructureview();
+ x = view[eventdata, 6];
+ y = view[eventdata, 7];
+ width = view[eventdata, 8];
+ height = view[eventdata, 9];
+ break;
+ case Expose:
+ view = getexposeview();
+ x = view[eventdata, 5];
+ y = view[eventdata, 6];
+ width = view[eventdata, 7];
+ height = view[eventdata, 8];
+ break;
+ case KeyPress:
+ view = getkeyview();
+ x = view[eventdata, 8];
+ y = view[eventdata, 9];
+ x_root = view[eventdata, 10];
+ y_root = view[eventdata, 11];
+ keycode = view[eventdata, 13];
+ break;
+ case ButtonPress:
+ case ButtonRelease:
+ view = getbuttonview();
+ x = view[eventdata, 8];
+ y = view[eventdata, 9];
+ x_root = view[eventdata, 10];
+ y_root = view[eventdata, 11];
+ button = view[eventdata, 13];
+ break;
+ case MotionNotify:
+ view = getmotionview();
+ x = view[eventdata, 8];
+ y = view[eventdata, 9];
+ x_root = view[eventdata, 10];
+ y_root = view[eventdata, 11];
+ break;
+ }
+ self.evx =: x;
+ self.evy =: y;
+ self.evx_root =: x_root;
+ self.evy_root =: y_root;
+ self.evwidth =: width;
+ self.evheight =: height;
+ self.evkeycode =: keycode;
+ self.evbutton =: button;
+ }
+ function type()
+ {
+ return int(self.evtype);
+ }
+ function serial()
+ {
+ int t = self.anyview[self.eventdata, 1];
+ return t;
+ }
+ function window()
+ {
+ int t = self.anyview[self.eventdata, 4];
+ return t;
+ }
+ function time()
+ {
+ int t = self.anyview[self.eventdata, 7];
+ return t;
+ }
+ function x()
+ {
+ return int(self.evx);
+ }
+ function y()
+ {
+ return int(self.evy);
+ }
+ function x_root()
+ {
+ return int(self.evx_root);
+ }
+ function y_root()
+ {
+ return int(self.evy_root);
+ }
+ function width()
+ {
+ return int(self.evwidth);
+ }
+ function height()
+ {
+ return int(self.evheight);
+ }
+ function keycode()
+ {
+ return int(self.evkeycode);
+ }
+ function button()
+ {
+ return int(self.evbutton);
+ }
+}
+
+//**************************************************************
+// Drawable
+//**************************************************************
+
+class Drawable
+{
+ var display;
+ var xdrawable;
+ var gc;
+ var font;
+ function getgc()
+ {
+ var gc = self.gc;
+ if (gc == null)
+ gc = self.display.DefaultGC();
+ return gc;
+ }
+ function owngc()
+ {
+ var gc = self.gc;
+ if (gc == null)
+ self.gc = gc = getfun("XCreateGC")
+ (self.display.xdisplay, self.xdrawable, null, 0);
+ return gc;
+ }
+ function SetForeground(string spec)
+ {
+ var gc = self.owngc();
+ int pixel = self.display.ParseColor(spec);
+ getfun("XSetForeground")(self.display.xdisplay, gc, pixel);
+ }
+ function DrawPoint(int x, int y)
+ {
+ __DEBUG__ && cry(__FUNCTION__, self.xdrawable);
+ var gc = self.getgc();
+ getfun("XDrawPoint")(self.display.xdisplay, self.xdrawable, gc, x, y);
+ __DEBUG__ && cry(__FUNCTION__ + " end");
+ }
+ function DrawLine(int x1, int y1, int x2, int y2)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ var gc = self.getgc();
+ getfun("XDrawLine")(self.display.xdisplay, self.xdrawable,
+ gc, x1, y1, x2, y2);
+ }
+ function DrawRectangle(int x, int y, int width, int height)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ var gc = self.getgc();
+ getfun("XDrawRectangle")(self.display.xdisplay, self.xdrawable,
+ gc, x, y, width, height);
+ }
+ function FillRectangle(int x, int y, int width, int height)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ var gc = self.getgc();
+ getfun("XFillRectangle")(self.display.xdisplay, self.xdrawable,
+ gc, x, y, width, height);
+ }
+ function SetFunction(int func)
+ {
+ var gc = self.owngc();
+ getfun("XSetFunction")(self.display.xdisplay, gc, func);
+ }
+ function SetLineAttributes(int width, int style, int cap, int join)
+ {
+ var gc = self.owngc();
+ getfun("XSetLineAttributes")(self.display.xdisplay, gc, width, style, cap, join);
+ }
+ function SetSubwindowMode(int mode)
+ {
+ var gc = self.owngc();
+ getfun("XSetSubwindowMode")(self.display.xdisplay, gc, mode);
+ }
+ function DrawString(int x, int y, string str)
+ {
+ var display = self.display;
+ var gc = self.owngc();
+ var font = self.font;
+ if (font == null) {
+ font = display.getDefaultFont();
+ self.font = font;
+ }
+ var xdisplay = display.xdisplay;
+ var xdrawable = self.xdrawable;
+ var pstr = str_to_cstring(str);
+ var len = bytelength(str);
+ if (font != null)
+ getfun("XmbDrawString")(xdisplay, xdrawable,
+ font, gc, x, y, pstr, len);
+ else
+ getfun("XDrawString")(xdisplay, xdrawable,
+ gc, x, y, pstr, len);
+ }
+}
+
+//**************************************************************
+// Window
+//**************************************************************
+
+class Window : Drawable
+{
+ function Destroy()
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ getfun("XDestroyWindow")(self.display.xdisplay, self.xdrawable);
+ }
+ function SelectInput(int eventmask)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ getfun("XSelectInput")(self.display.xdisplay, self.xdrawable, eventmask);
+ }
+ function StoreName(string name)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ getfun("XStoreName")(self.display.xdisplay, self.xdrawable,
+ str_to_cstring(name));
+ }
+ function SetWMProtocols(names)
+ {
+ self.display.SetWMProtocols(self, names);
+ }
+ function Map()
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ getfun("XMapWindow")(self.display.xdisplay, self.xdrawable);
+ }
+ function Unmap()
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ getfun("XUnmapWindow")(self.display.xdisplay, self.xdrawable);
+ }
+ function ClearArea(int x, int y, int width, int height, int exposures)
+ {
+ getfun("XClearArea")(self.display.xdisplay, self.xdrawable,
+ x, y, width, height, exposures);
+ }
+ function MoveWindow(int x, int y)
+ {
+ getfun("XMoveWindow")(self.display.xdisplay, self.xdrawable, x, y);
+ }
+ function RaiseWindow()
+ {
+ getfun("XRaiseWindow")(self.display.xdisplay, self.xdrawable);
+ }
+}
+
+//**************************************************************
+// Higher level
+//**************************************************************
+
+class Controller
+{
+ var display;
+ var regwindow;
+ var running;
+ function Controller()
+ {
+ self.Controller(new Display());
+ }
+ function Controller(display)
+ {
+ self.display = display;
+ self.regwindow = {};
+ }
+ function Close()
+ {
+ self.display.Close();
+ }
+ function setDefaultFont(string fontdesc)
+ {
+ self.display.setDefaultFont(fontdesc);
+ }
+ function register(window)
+ {
+ self.regwindow[window.xdrawable] = window;
+ }
+ function unregister(window)
+ {
+ var regwindow = self.regwindow;
+ if (exists regwindow[window.xdrawable])
+ delete regwindow[window.xdrawable];
+ }
+ function handleEvent(event)
+ {
+ using namespace Events;
+ int w = event.window();
+ var window = self.regwindow[w];
+ if (window != null)
+ window.handle(event);
+ }
+ function MainLoop()
+ {
+ self.running = true;
+ var display = self.display;
+ var event = new Event();
+ do {
+ display.NextEvent(event);
+ self.handleEvent(event);
+ } while (self.running);
+ }
+ function Quit()
+ {
+ self.running = false;
+ }
+}
+
+class EventHandler
+{
+ var window;
+ var selectmask;
+ var handlers;
+ function EventHandler(window, mask)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ self.window = window;
+ self.selectmask = mask;
+ self.handlers = [];
+ }
+ function i_add [vtable] (newhandler)
+ {
+ push(self.handlers, newhandler);
+ self.window.addmask(self.selectmask);
+ }
+ function handle(event)
+ {
+ for (var handler in self.handlers)
+ handler(event);
+ }
+}
+
+class ListenerWindow : Window
+{
+ var controller;
+ var mask;
+ var OnConfigure;
+ var OnExpose;
+ var OnKeyPress;
+ var OnButtonPress;
+ var OnButtonRelease;
+ var OnMotion;
+ var OnDestroy;
+ var OnClientMessage;
+ function ListenerWindow(controller)
+ {
+ self.mask = 0;
+ self.OnConfigure = new EventHandler(self, StructureNotifyMask);
+ self.OnExpose = new EventHandler(self, ExposureMask);
+ self.OnKeyPress = new EventHandler(self, KeyPressMask);
+ self.OnButtonPress = new EventHandler(self, ButtonPressMask);
+ self.OnButtonRelease = new EventHandler(self, ButtonReleaseMask);
+ self.OnMotion = new EventHandler(self, PointerMotionMask);
+ self.OnDestroy = new EventHandler(self, StructureNotifyMask);
+ self.OnClientMessage = new EventHandler(self, 0);
+ self.controller = controller;
+ controller.register(self);
+ }
+ function addmask(int newmask)
+ {
+ int mask = self.mask;
+ newmask = newmask | mask;
+ if (newmask != mask) {
+ self.mask =: newmask;
+ self.SelectInput(newmask);
+ }
+ }
+ function handle(event)
+ {
+ var handler;
+ switch (event.type()) {
+ case ConfigureNotify:
+ handler = self.OnConfigure;
+ break;
+ case Expose:
+ handler = self.OnExpose;
+ break;
+ case KeyPress:
+ handler = self.OnKeyPress;
+ break;
+ case ButtonPress:
+ handler = self.OnButtonPress;
+ break;
+ case ButtonRelease:
+ handler = self.OnButtonRelease;
+ break;
+ case MotionNotify:
+ handler = self.OnMotion;
+ break;
+ case DestroyNotify:
+ handler = self.OnDestroy;
+ break;
+ case ClientMessage:
+ handler = self.OnClientMessage;
+ break;
+ }
+ if (handler != null)
+ handler.handle(event);
+ }
+}
+
+class TopLevelWindow : ListenerWindow
+{
+ var controller;
+ function TopLevelWindow(controller, string title,
+ int x, int y, int width, int height)
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ var display = controller.display;
+ self.display = display;
+ self.xdrawable = display.CreateSimpleWindow(x, y, width, height);
+ self.StoreName(title);
+ self.ListenerWindow(controller);
+ }
+}
+
+class ChildWindow : ListenerWindow
+{
+ function ChildWindow(parent, int x, int y, int width, int height,
+ style[optional])
+ {
+ __DEBUG__ && cry(__FUNCTION__);
+ var display = parent.controller.display;
+ self.display = display;
+ int border_width = 0;
+ int border_color = 0;
+ int background = display.WhitePixel(0);
+ if (style != null) {
+ if (exists style["background_color"])
+ background = style["background_color"];
+ }
+ self.xdrawable = display.CreateSimpleChildWindow(parent,
+ x, y, width, height, border_width, border_color, background);
+ self.ListenerWindow(parent.controller);
+ }
+}
+
+} // namespace Guitor
+
+// End.
456 src/GuitorNci.winxed
@@ -0,0 +1,456 @@
+#! winxed
+
+// GuitorNci.winxed
+
+// Xlib NCI for Guitor
+
+namespace Guitor
+{
+
+//**************************************************************
+// Internal helper functions
+//**************************************************************
+
+namespace Xlib__private
+{
+
+$include_const "datatypes.pasm";
+
+// Variable names
+const string
+ XLIB = "winxed_xlib",
+ EVENTPAD = "winxed_eventpad",
+ ANYVIEW = "winxed_anyview",
+ BUTTONVIEW = "winxed_buttonview",
+ KEYVIEW = "winxed_keyview",
+ MOTIONVIEW = "winxed_motionview",
+ STRUCTUREVIEW = "winxed_structureview",
+ EXPOSEVIEW = "winxed_exposeview",
+ ATOMVIEW = "winxed_atomview",
+ XCOLORVIEW = "winxed_xcolorview";
+
+function loadXlib()
+{
+ string libs[] = [
+ "libX11",
+ "libX11.so",
+ "libX11.so.6",
+ "/usr/lib/libX11.so",
+ "/usr/lib/libX11.so.6",
+ "cygX11-6"
+ ];
+ var l;
+ for (string lib in libs) {
+ l= loadlib(lib);
+ if (l) break;
+ }
+ return l;
+}
+
+function getlib()
+{
+ var ns = namespace Xlib__private;
+ var l = ns[XLIB];
+ if (l == null)
+ ns[XLIB] = l = loadXlib();
+ return l;
+}
+
+//**************************************************************
+/*
+ Event structure definition.
+ Values used for sizes and offsets are derived
+ from Xlib docs and testing in several platforms.
+*/
+
+const int XLIB_Bool = DATATYPE_INT32;
+const int XLIB_time_t = DATATYPE_LONG;
+const int XLIB_Window = DATATYPE_LONG;
+
+function create_eventpad()
+{
+ const int PAD = 24;
+ int viewdata [PAD + 2] = [ DATATYPE_STRUCT, PAD ];
+ for (int i = 0; i < PAD; ++i)
+ viewdata[i + 2] = DATATYPE_LONG;
+ var view = new ["StructView"](viewdata);
+ return view;
+}
+
+function create_anyview()
+{
+ int viewdata [] = [
+ DATATYPE_STRUCT, 5,
+ DATATYPE_INT, // type
+ DATATYPE_LONG, // Serial
+ XLIB_Bool, // send event
+ DATATYPE_PTR, // display
+ XLIB_Window // window
+ ];
+ var view = new ["StructView"](viewdata);
+ return view;
+}
+
+function create_buttonview()
+{
+ int viewdata [] = [
+ DATATYPE_STRUCT, 14,
+ DATATYPE_INT, // type
+ DATATYPE_LONG, // Serial
+ XLIB_Bool, // send event
+ DATATYPE_PTR, // display
+ XLIB_Window, // window
+ XLIB_Window, // root
+ XLIB_Window, // subwindow
+ XLIB_time_t, // time
+ DATATYPE_INT, // x
+ DATATYPE_INT, // y
+ DATATYPE_INT, // x_root
+ DATATYPE_INT, // y_root
+ DATATYPE_INT, // state
+ DATATYPE_INT, // button
+ XLIB_Bool // same_screen
+ ];
+ var view = new ["StructView"](viewdata);
+ return view;
+}
+
+function create_keyview()
+{
+ int viewdata [] = [
+ DATATYPE_STRUCT, 14,
+ DATATYPE_INT, // type
+ DATATYPE_LONG, // Serial
+ XLIB_Bool, // send event
+ DATATYPE_PTR, // display
+ XLIB_Window, // window
+ XLIB_Window, // root
+ XLIB_Window, // subwindow
+ XLIB_time_t, // time
+ DATATYPE_INT, // x
+ DATATYPE_INT, // y
+ DATATYPE_INT, // x_root
+ DATATYPE_INT, // y_root
+ DATATYPE_INT, // state
+ DATATYPE_INT, // keycode
+ XLIB_Bool // same_screen
+ ];
+ var view = new ["StructView"](viewdata);
+ return view;
+}
+
+function create_motionview()
+{
+ int viewdata [] = [
+ DATATYPE_STRUCT, 14,
+ DATATYPE_INT, // type
+ DATATYPE_LONG, // Serial
+ XLIB_Bool, // send event
+ DATATYPE_PTR, // display
+ XLIB_Window, // window
+ XLIB_Window, // root
+ XLIB_Window, // subwindow
+ XLIB_time_t, // time
+ DATATYPE_INT, // x
+ DATATYPE_INT, // y
+ DATATYPE_INT, // x_root
+ DATATYPE_INT, // y_root
+ DATATYPE_INT, // state
+ DATATYPE_INT // keycode
+ ];
+ var view = new ["StructView"](viewdata);
+ return view;
+}
+
+function create_structureview()
+{
+ int viewdata [] = [
+ DATATYPE_STRUCT, 13,
+ DATATYPE_INT, // type
+ DATATYPE_LONG, // Serial
+ XLIB_Bool, // send event
+ DATATYPE_PTR, // display
+ XLIB_Window, // event window
+ XLIB_Window, // window
+ DATATYPE_INT, // x
+ DATATYPE_INT, // y
+ DATATYPE_INT, // width
+ DATATYPE_INT, // height
+ DATATYPE_INT, // border_width
+ XLIB_Window, // above
+ XLIB_Bool // override_redirect
+ ];
+ var view = new ["StructView"](viewdata);
+ return view;
+}
+
+function create_exposeview()
+{
+ int viewdata [] = [
+ DATATYPE_STRUCT, 10,
+ DATATYPE_INT, // type
+ DATATYPE_LONG, // Serial
+ XLIB_Bool, // send event
+ DATATYPE_PTR, // display
+ XLIB_Window, // window
+ DATATYPE_INT, // x
+ DATATYPE_INT, // y
+ DATATYPE_INT, // width
+ DATATYPE_INT, // height
+ DATATYPE_INT // count
+ ];
+ var view = new ["StructView"](viewdata);
+ return view;
+}
+
+//**************************************************************
+
+function geteventpad()
+{
+ var ns = namespace Xlib__private;
+ var st = ns[EVENTPAD];
+ if (st == null)
+ ns[EVENTPAD] = st = create_eventpad();
+ return st;
+}
+
+function getanyview()
+{
+ var ns = namespace Xlib__private;
+ var st = ns[ANYVIEW];
+ if (st == null)
+ ns[ANYVIEW] = st = create_anyview();
+ return st;
+}
+
+function getbuttonview()
+{
+ var ns = namespace Xlib__private;
+ var st = ns[BUTTONVIEW];
+ if (st == null)
+ ns[BUTTONVIEW] = st = create_buttonview();
+ return st;
+}
+
+function getkeyview()
+{
+ var ns = namespace Xlib__private;
+ var st = ns[KEYVIEW];
+ if (st == null)
+ ns[KEYVIEW] = st = create_keyview();
+ return st;
+}
+
+function getmotionview()
+{
+ var ns = namespace Xlib__private;
+ var st = ns[MOTIONVIEW];
+ if (st == null)
+ ns[MOTIONVIEW] = st = create_motionview();
+ return st;
+}
+
+function getstructureview()
+{
+ var ns = namespace Xlib__private;
+ var st = ns[STRUCTUREVIEW];
+ if (st == null)
+ ns[STRUCTUREVIEW] = st = create_structureview();
+ return st;
+}
+
+function getexposeview()
+{
+ var ns = namespace Xlib__private;
+ var st = ns[EXPOSEVIEW];
+ if (st == null)
+ ns[EXPOSEVIEW] = st = create_exposeview();
+ return st;
+}
+
+function getatomview()
+{
+ var ns = namespace Xlib__private;
+ var st = ns[ATOMVIEW];
+ if (st == null)
+ ns[ATOMVIEW] = st = new ["StructView"]
+ ( [ DATATYPE_STRUCT, 1, DATATYPE_INT ] );
+ return st;
+}
+
+function getxcolorview()
+{
+ var ns = namespace Xlib__private;
+ var st = ns[XCOLORVIEW];
+ if (st == null)
+ ns[XCOLORVIEW] = st = new ["StructView"]( [ DATATYPE_STRUCT, 6,
+ DATATYPE_LONG, // pixel
+ DATATYPE_SHORT, // red
+ DATATYPE_SHORT, // green
+ DATATYPE_SHORT, // blue
+ DATATYPE_CHAR, // flags
+ DATATYPE_CHAR // pad
+ ] );
+ return st;
+}
+
+//**************************************************************
+
+function create_function(string funcname)
+{
+ string sig;
+ switch (funcname) {
+ case "XDisplayName":
+ case "XOpenDisplay":
+ sig = "pp";
+ break;
+ case "XCloseDisplay":
+ case "XDefaultScreen":
+ case "XStringToKeysym":
+ case "XSetLocaleModifiers":
+ sig = "ip";
+ break;
+ case "setlocale":
+ sig = "pip";
+ break;
+ case "XDefaultGC":
+ case "XDefaultColormap":
+ sig = "ppi";
+ break;
+ case "XRootWindow":
+ sig = "ipi";
+ break;
+ case "XDefaultDepth":
+ case "XBlackPixel":
+ case "XWhitePixel":
+ case "XKeysymToKeycode":
+ sig = "ipi";
+ break;
+ case "XCreateGC":
+ sig = "ppipi";
+ break;
+ case "XSetForeground":
+ sig = "vppi";
+ break;
+ case "XMapWindow":
+ case "XUnmapWindow":
+ sig = "ipi";
+ break;
+ case "XDestroyWindow":
+ sig = "ipi";
+ break;
+ case "XRaiseWindow":
+ sig = "vpi";
+ break;
+ case "XSetFunction":
+ sig = "vppi";
+ break;
+ case "XNextEvent":
+ sig = "ipp";
+ break;
+ case "XKeycodeToKeysym":
+ sig = "ipii";
+ break;
+ case "XKeysymToString":
+ sig = "pi";
+ break;
+ case "XLookupString":
+ sig = "ippipp";
+ break;
+ case "XSelectInput":
+ sig = "ipii";
+ break;
+ case "XInternAtom":
+ sig = "ippi";
+ break;
+ case "XStoreName":
+ sig = "ipip";
+ break;
+ case "XDrawPoint":
+ sig = "ipipii";
+ break;
+ case "XDrawLine":
+ case "XDrawRectangle":
+ case "XFillRectangle":
+ sig = "ipipiiii";
+ break;
+ case "XClearArea":
+ sig = "ipiiiiii";
+ break;
+ case "XCreateSimpleWindow":
+ sig = "ipiiiiiiii";
+ break;
+ case "XSetWMProtocols":
+ sig = "ipipi";
+ break;
+ case "XMoveWindow":
+ sig = "ipiii";
+ break;
+ case "XParseColor":
+ sig = "ipppp";
+ break;
+ case "XAllocColor":
+ sig = "ippp";
+ break;
+ case "XDrawString":
+ sig = "vpipiipi";
+ break;
+ case "XmbDrawString":
+ case "Xutf8DrawString":
+ sig = "vpippiipi";
+ break;
+ case "XCreateFontSet":
+ sig = "pppppp";
+ break;
+ case "XSetLineAttributes":
+ sig = "vppiiii";
+ break;
+ case "XSetSubwindowMode":
+ sig = "vppi";
+ break;
+ default:
+ throw "Function " + funcname + " unknown";
+ }
+ var func = dlfunc(getlib(), funcname, sig);
+ return func;
+}
+
+//**************************************************************
+
+function str_to_cstring(string s)
+{
+ var cstring = new ["ByteBuffer"];
+ cstring =: trans_encoding(s, "utf8");
+ push(cstring, 0);
+ return cstring;
+}
+
+function string_from_nci(p)
+{
+ string s;
+ if (p != null)
+ s = p.as_string("utf8");
+ return s;
+}
+
+function newAtomlist(int n)
+{
+ var view = getatomview();
+ var data = view.alloc(n);
+ return data;
+}
+
+function getfun(string funcname)
+{
+ var ns = namespace Xlib__private;
+ var fun = ns[funcname];
+ if (fun == null)
+ ns[funcname] = fun = create_function(funcname);
+ return fun;
+}
+
+} // namespace Xlib__private
+
+} // namespace Guitor
+
+// End
Please sign in to comment.
Something went wrong with that request. Please try again.