From 0500b0c7126192801c9e20607edbc0298cddece7 Mon Sep 17 00:00:00 2001 From: sbosse Date: Mon, 21 Jul 2025 23:03:26 +0200 Subject: [PATCH] Mon 21 Jul 22:43:21 CEST 2025 --- js/x11/core/ext/glx.js | 325 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 js/x11/core/ext/glx.js diff --git a/js/x11/core/ext/glx.js b/js/x11/core/ext/glx.js new file mode 100644 index 0000000..6a78bfc --- /dev/null +++ b/js/x11/core/ext/glx.js @@ -0,0 +1,325 @@ +/* + second extension to try + links to get started: + + http://cgit.freedesktop.org/xcb/proto/tree/src/glx.xml?id=HEAD + http://cgit.freedesktop.org/mesa/mesa/tree/src/glx + http://cgit.freedesktop.org/mesa/mesa/tree/src/glx/indirect.c + + http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX) + + https://github.com/xderoche/J11/blob/master/src/gnu/x11/extension/glx/GL.java + + +*/ +var x11 = Require('x11/core/x11'); +// TODO: move to templates +exports.requireExt = function(display, callback) +{ + var X = display.client; + X.QueryExtension('GLX', function(err, ext) { + var constants = require('./glxconstants'); + for (var i in constants) + ext[i] = constants[i]; + + if (!ext.present) + return callback(new Error('extension not available')); + + ext.QueryVersion = function(clientMaj, clientMin, callback) + { + X.seq_num++; + X.pack_stream.pack('CCSLL', [ext.majorOpcode, 7, 3, clientMaj, clientMin]); + X.replies[X.seq_num] = [ + function(buf, opt) { + var res = buf.unpack('LL'); + return res; + }, + callback + ]; + X.pack_stream.flush(); + } + + ext.QueryServerString = function(screen, name, callback) { + X.seq_num++; + X.pack_stream.pack('CCSLL', [ext.majorOpcode, 19, 3, screen, name]); + X.replies[X.seq_num] = [ + function(buf, opt) { + var len = buf.unpack('xxxxL')[0]; + return buf.toString().substring(24, 24+len*4); + }, + callback + ]; + X.pack_stream.flush(); + } + + ext.CreateGLXPixmap = function(screen, visual, pixmap, glxpixmap) { + X.seq_num++; + X.pack_stream.pack('CCSLLLL', [ext.majorOpcode, 13, 5, screen, visual, pixmap, glxpixmap]); + + console.log('CreateGlxPix', X.seq_num); + console.log(ext.majorOpcode, 13, 5, screen, visual, pixmap, glxpixmap); + console.trace(); + + + X.pack_stream.flush(); + } + + ext.QueryExtensionsString = function(screen, callback) { + X.seq_num++; + X.pack_stream.pack('CCSL', [ext.majorOpcode, 18, 2, screen]); + X.replies[X.seq_num] = [ + function(buf, opt) { + var len = buf.unpack('xxxxL')[0]; + return buf.toString().substring(24, 24+len*4); + }, + callback + ]; + X.pack_stream.flush(); + } + + // see __glXInitializeVisualConfigFromTags in mesa/src/glx/glxext.c + // + ext.GetVisualConfigs = function(screen, callback) { + X.seq_num++; + X.pack_stream.pack('CCSL', [ext.majorOpcode, 14, 2, screen]); + X.replies[X.seq_num] = [ + function(buf, opt) { + var res = buf.unpack('LL'); + var numConfigs = res[0]; + var numProps = res[1]; + var configs = new Array(numConfigs); + var i,j; + for (i=0; i < numConfigs; ++i) { + var props = {}; //new Array(numProps); + var names = 'visualID visualType rgbMode redBits greenBits blueBits alphaBits accumRedBits accumGreen accumBlueBits accumAlphaBits doubleBufferMode stereoMode rgbBits depthBits stencilBits numAuxBuffers level'.split(' '); + for (var j=0; j < 18 && j < numProps; ++j) { + props[names[j]] = buf.unpack('L', 24+(i*numProps +j)*4)[0]; + } + // read tag + property + configs[i] = props; + } + + return configs; + }, + callback + ]; + X.pack_stream.flush(); + } + + ext.GetFBConfigs = function(screen, callback) { + X.seq_num++; + X.pack_stream.pack('CCSL', [ext.majorOpcode, 21, 2, screen]); + X.replies[X.seq_num] = [ + function(buf, opt) { + var res = buf.unpack('LL'); + var numConfigs = res[0]; + var numProps = res[1]; + var configs = new Array(numConfigs); + var i,j; + for (i=0; i < numConfigs; ++i) { + var props = new Array(numProps); + for (var j=0; j < numProps; ++j) { + props[j] = buf.unpack('LL', 24+(i*numProps +j)*8); + } + configs[i] = props; + } + return configs; + }, + callback + ]; + X.pack_stream.flush(); + } + + ext.CreateContext = function(ctx, visual, screen, shareListCtx, isDirect) + { + X.seq_num++; + X.pack_stream.pack('CCSLLLLCxxx', [ext.majorOpcode, 3, 6, ctx, visual, screen, shareListCtx, isDirect]); + X.pack_stream.flush(); + } + + ext.SwapBuffers = function(ctx, drawable) + { + X.seq_num++; + X.pack_stream.pack('CCSLL', [ext.majorOpcode, 11, 3, ctx, drawable]); + X.pack_stream.flush(); + } + + ext.NewList = function(ctx, list, mode) + { + X.seq_num++; + X.pack_stream.pack('CCSLLL', [ext.majorOpcode, 101, 4, ctx, list, mode]); + X.pack_stream.flush(); + } + + ext.EndList = function(ctx) + { + X.seq_num++; + X.pack_stream.pack('CCSL', [ext.majorOpcode, 102, 2, ctx]); + X.pack_stream.flush(); + } + + ext.GenLists = function(ctx, count, callback) + { + X.seq_num++; + X.pack_stream.pack('CCSLL', [ext.majorOpcode, 104, 3, ctx, count]); + X.replies[X.seq_num] = [ + function(buf, opt) { + return buf.unpack('L')[0]; + }, + callback + ]; + X.pack_stream.flush(); + } + + ext.GenTextures = function(ctx, count, callback) + { + X.seq_num++; + X.pack_stream.pack('CCSLL', [ext.majorOpcode, 145, 3, ctx, count]); + X.replies[X.seq_num] = [ + function(buf, opt) { + var format = Buffer(count); + format.fill('L'); + return buf.unpack('xxxxxxxxxxxxxxxxxxxxxxxx' + format.toString()); + }, + callback + ]; + X.pack_stream.flush(); + } + + ext.IsTexture = function(ctx, texture, callback) + { + X.seq_num++; + X.pack_stream.pack('CCSLL', [ext.majorOpcode, 146, 3, ctx, texture]); + X.replies[X.seq_num] = [ + function(buf, opt) { + return buf.unpack('CCCCCCCCCCCCCCCCCCCCCCCCCC'); + }, + callback + ]; + X.pack_stream.flush(); + } + + ext.MakeCurrent = function(drawable, ctx, oldctx, callback) + { + X.seq_num++; + X.pack_stream.pack('CCSLLL', [ext.majorOpcode, 5, 4, drawable, ctx, oldctx]); + X.replies[X.seq_num] = [ + function(buf, opt) { + return buf.unpack('L')[0]; + }, + callback + ]; + X.pack_stream.flush(); + } + + ext.Finish = function(ctx, callback) + { + X.seq_num++; + X.pack_stream.pack('CCSL', [ext.majorOpcode, 108, 2, ctx]); + X.replies[X.seq_num] = [ + function(buf, opt) { + return; + }, + callback + ]; + X.pack_stream.flush(); + } + + ext.Render = function(ctx, data) { + X.seq_num++; + var length = 0; + if (Buffer.isBuffer(data)) + length = 2+data.length/4; + else if (Array.isArray(data)) { + length = 2; + for (var i=0; i < data.length; ++i) + length += data[i].length/4; + } + X.pack_stream.pack('CCSL', [ext.majorOpcode, 1, length, ctx]); + if (Buffer.isBuffer(data)) + X.pack_stream.write_queue.push(data); + else if (Array.isArray(data)) + for (var i=0; i < data.length; ++i) + X.pack_stream.write_queue.push(data[i]); + else + throw new Error('invalid data, expected buffer or buffers array', data); + X.pack_stream.flush(); + } + + ext.VendorPrivate = function(ctx, code, data) { + X.seq_num++; + X.pack_stream.pack('CCSLL', [ext.majorOpcode, 16, 3+data.length/4, code, ctx]); + X.pack_stream.write_queue.push(data); + X.pack_stream.flush(); + } + + // 1330 - X_GLXvop_BindTexImageEXT + // 1331 - X_GLXvop_ReleaseTexImageEXT + ext.BindTexImage = function(ctx, drawable, buffer, attribs) { + if (!attribs) + attribs = []; + var data = new Buffer(12 + attribs.length*4); + data.writeUInt32LE(drawable, 0); + data.writeUInt32LE(buffer, 4); + data.writeUInt32LE(attribs.length, 8); + for (var i=0; i < attribs.length; ++i) + data.writeUint32LE(attribs.length, 12+i*4); + ext.VendorPrivate(ctx, 1330, data); + } + + ext.ReleaseTexImage = function(ctx, drawable, buffer) { + var data = new Buffer(8); + data.writeUint32LE(drawable, 0); + data.writeUint32LE(buffer, 4); + ext.VendorPrivate(ctx, 1331, data); + } + + // VendorPrivateWithReply - opcode 17 + + ext.RenderLarge = function(ctx, requestNum, requestTotal, data) { + X.seq_num++; + + //var data = Buffer.concat(data); + var padLength = 4 - data.length % 4; + if (padLength == 4) + padLength = 0; + var length = 4 + (data.length+padLength) / 4; + X.pack_stream.pack('CCSLSSL', [ext.majorOpcode, 2, length, ctx, requestNum, requestTotal, data.length]); + + X.pack_stream.write_queue.push(data); + var pad = new Buffer(padLength); + pad.fill(0); + X.pack_stream.write_queue.push(pad); + X.pack_stream.flush(); + } + + ext.renderPipeline = function(ctx) { + return require('./glxrender')(this, ctx); + } + + var errors = [ + "context", + "contect state", + "drawable", + "pixmap", + "context tag", + "current window", + "Render request", + "RenderLarge request", + "(unsupported) VendorPrivate request", + "FB config", + "pbuffer", + "current drawable", + "window" + ]; + + errors.forEach(function(message, code) { + X.errorParsers[ext.firstError + code] = function(err) { + err.message = "GLX: Bad " + message; + }; + }); + + callback(null, ext); + }); +} +