Console Device.

12 posts / 0 new
Last post
afxgroup
afxgroup's picture
Offline
Last seen: 10 months 2 weeks ago
Joined: 2011-02-03 15:26
Console Device.

I'm trying to get CDT_GETROWS and CDT_GETCOLUMNS from the active shell window (so no new windows opened).
I've use this code but it crash in DoIO()

  1. struct Process *me = (struct Process *) FindTask(NULL);
  2. struct MsgPort *consolePort = me->pr_ConsolePort;
  3. if (consolePort != NULL) {
  4. struct IOStdReq *writeReq = AllocSysObjectTags(ASOT_IOREQUEST,
  5. ASOIOR_Size, sizeof(struct IOStdReq),
  6. ASOIOR_ReplyPort, consolePort,
  7. TAG_END);
  8. if (writeReq != NULL) {
  9. struct TagItem tags[3];
  10. uint32 cols, rows, xcp, ycp;
  11.  
  12. printf("Setup tags\n");
  13. tags[0].ti_Tag = CDT_GETROWS;
  14. tags[0].ti_Data = (uint32) &cols;
  15. tags[1].ti_Tag = CDT_GETCOLUMNS;
  16. tags[1].ti_Data = (uint32) &rows;
  17. tags[2].ti_Tag = TAG_END;
  18.  
  19. writeReq->io_Command = CD_GETATTRS;
  20. writeReq->io_Data = tags;
  21. writeReq->io_Length = sizeof(tags);
  22. DoIO((struct IORequest *) writeReq);
  23. ...more code below..

My question is. Is it possible to use the process console's message port? Is there any other way to do this? I didn't find any great documentation how to handle the current shell console device

hypex
hypex's picture
Offline
Last seen: 1 month 2 weeks ago
Joined: 2011-09-09 16:20
Re: Console Device.

I'm not surprised. That's a strange way of coding it. You've taken a message port then used it in a device call without opening any device. How confusing! :-D

First, rather than read directly you can use GetConsolePort() from DOS to also grab it. Second, if I read the API correctly, it's a port for DOS packets. So you would need to send it a DOS packet. Third, SendPkt() is good for that after allocating a packet.

Looks like you could open console.device the usual way and specify the Process->pr_WindowPtr but I can't find much info that way. It's likely in some Amiga book somewhere. I read about it years ago but not so sure about interfacing it with a shell window.

Regardless, if your intention is to simplly find the matrix columns and rows it may just be easier to use a CSI sequence to do the job and read it back from stdin. Check this section about CSI. At the top is more info about using console.device directly.

https://wiki.amigaos.net/wiki/Console_Device#Cursor_Position_Report

afxgroup
afxgroup's picture
Offline
Last seen: 10 months 2 weeks ago
Joined: 2011-02-03 15:26
Re: Console Device.

GetConsolePort() return the same pointer. So no difference using it or using pr_ConsolePort.
Theoretically (but of course i'm not so sure about this because there is no documentation) the console.device should be already opened for that Message Port.
I'll try top open console.device using the window pointer to see if it works
However my intention is not to find current row and column (the CSI you poninted at) but Window's rows and columns and from the doc CD_GETATTRS should do the trick

afxgroup
afxgroup's picture
Offline
Last seen: 10 months 2 weeks ago
Joined: 2011-02-03 15:26
Re: Console Device.

However even allocating a port with ASOT_PORT and using it in ASOT_IOREQUEST, when trying to open console.device using writeReq->io_Data = (APTR)me->pr_WindowPtr; doesn't work. console.device cannot be opened

afxgroup
afxgroup's picture
Offline
Last seen: 10 months 2 weeks ago
Joined: 2011-02-03 15:26
Re: Console Device.

I've even tried to get the window pointer like Olsen wrote here:

https://forum.amiga.org/index.php?topic=73249.0

But no luck..

afxgroup
afxgroup's picture
Offline
Last seen: 10 months 2 weeks ago
Joined: 2011-02-03 15:26
Re: Console Device.

Ok. i've found a way to make it work. This is the code (updated) if anyone want to use it:

  1. #define ACTION_UNDISK_INFO 513L
  2. BOOL success = FALSE;
  3. struct InfoData id __attribute__ ((aligned));
  4. struct Window *window;
  5. struct Process *me = (struct Process *) FindTask(NULL);
  6. struct MsgPort *con = me->pr_ConsolePort;
  7. DoPkt1(con, ACTION_HANDLER_INFO, MKBADDR(&id));
  8. window = (struct Window *)id.id_VolumeNode;
  9. if (window) {
  10. struct MsgPort *consolePort = AllocSysObjectTags(ASOT_PORT,
  11. ASOPORT_Name, "clib2.console.query",
  12. TAG_END);
  13. /* Get Console port from process */
  14. if (consolePort != NULL) {
  15. int8 error;
  16. struct IOStdReq *writeReq = NULL;
  17. /* Allocate a IO request using console port */
  18. writeReq = AllocSysObjectTags(ASOT_IOREQUEST,
  19. ASOIOR_Size, sizeof(struct IOStdReq),
  20. ASOIOR_ReplyPort, consolePort,
  21. TAG_END);
  22. if (writeReq != NULL) {
  23. writeReq->io_Data = (APTR) window;
  24. writeReq->io_Length = sizeof(struct Window);
  25. error = OpenDevice("console.device", 0, (struct IORequest *) writeReq, 0);
  26. if (error == 0) {
  27. struct TagItem tags[3];
  28. uint32 cols, rows, xcp, ycp;
  29. tags[0].ti_Tag = CDT_GETROWS;
  30. tags[0].ti_Data = (uint32) & rows;
  31. tags[1].ti_Tag = CDT_GETCOLUMNS;
  32. tags[1].ti_Data = (uint32) & cols;
  33. tags[2].ti_Tag = TAG_END;
  34. /* Send GETATTRS message */
  35. writeReq->io_Command = CD_GETATTRS;
  36. writeReq->io_Data = &tags;
  37. writeReq->io_Length = sizeof(tags);
  38. DoIO((struct IORequest *) writeReq);
  39. CloseDevice((struct IORequest *) writeReq);
  40. /* Free IO request */
  41. FreeSysObject(ASOT_PORT, consolePort);
  42. FreeSysObject(ASOT_IOREQUEST, writeReq);
  43. writeReq = NULL;
  44. consolePort = NULL;
  45. success = TRUE;
  46. } else {
  47. FreeSysObject(ASOT_PORT, consolePort);
  48. consolePort = NULL;
  49. FreeSysObject(ASOT_IOREQUEST, writeReq);
  50. writeReq = NULL;
  51. }
  52. } else {
  53. FreeSysObject(ASOT_PORT, consolePort);
  54. consolePort = NULL;
  55. }
  56. }
  57. }

The problem is that the window console is cleared above the current line.. and i don't know why..

hypex
hypex's picture
Offline
Last seen: 1 month 2 weeks ago
Joined: 2011-09-09 16:20
Re: Console Device.

Yes, GetConsolePort() returns the same pointer, but it looks cleaner. :-)

Also, if there are any changes to the internals and there usually are, it's recommended to use a function than read it directly.

Looks like you figured out the quirks of console.device. That guide to the units looked over complicated. Thing like getting the window of a shell are always too complicated on AmigaOS.

You would be right, the console.device would already be opened. But it may not be using that port for device I/O and the little I found suggests it is used for DOS packets. And in programming the API it's right and proper to open it for your own use. It's wrong to use it just because it is opened, you must ask permission first. That's the design. :-)

Also, you don't need to give message ports a name. Unless they are made public. While I don't think it hurts, for private use they can remain nameless.

Regarding the CSI, I was actually thinking of the one below it, but thought it better to expand it. Pointing to the whole section may have helped better.

I'm not sure about this ACTION_UNDISK_INFO as I never heard of it until now. Things like a window can go away but it usually happens when the file handle is closed. In which case the file handle will be totally invalid as well. What if you take that packet out? Still get the screen clearing?

afxgroup
afxgroup's picture
Offline
Last seen: 10 months 2 weeks ago
Joined: 2011-02-03 15:26
Re: Console Device.

Looks like you figured out the quirks of console.device. That guide to the units looked over complicated. Thing like getting the window of a shell are always too complicated on AmigaOS.

The funny thing is that if you resize the window the content is repainted correcty. I've sent a message to Tony to see if he can reproduce the problem

Regarding the CSI, I was actually thinking of the one below it, but thought it better to expand it. Pointing to the whole section may have helped better.

I'll test this method to see if i have the same problem. Howerver since there is a new Command in console.device why don't use it?

I'm not sure about this ACTION_UNDISK_INFO as I never heard of it until now. Things like a window can go away but it usually happens when the file handle is closed. In which case the file handle will be totally invalid as well. What if you take that packet out? Still get the screen clearing?

I didn't try. However i get the code from the example i've found on amiga.org. I didn't find any documentation how to do this. And i've also checked the window pointers (that one in Process struct and that one retrieved via DoPkt1) and they are different. And the process one returns wrong cols and rows

afxgroup
afxgroup's picture
Offline
Last seen: 10 months 2 weeks ago
Joined: 2011-02-03 15:26
Re: Console Device.

Even without ACTION_UNDISK_INFO i get the same effect. But i've also noticed another problem
Every time you execute this code, a Window is created (you can see it with Ranger) and on Sam440 where I have the blinking cursor i can see the blinking cursor on top-left. I've noticed also that console.device counter is increased every time and doesn't decrease on CloseDevice.
It is possible that something still opened (the window)?

Edit:
This problem was caused by a wrong sequence of freeing stuff. I was closing the device after freeing objects that of course is wrong

afxgroup
afxgroup's picture
Offline
Last seen: 10 months 2 weeks ago
Joined: 2011-02-03 15:26
Re: Console Device.

A different approach using escape sequences:

  1. #include <proto/dos.h>
  2. #include <stdio.h>
  3.  
  4. int main(void)
  5. {
  6. BPTR fh = Open("CONSOLE:", MODE_OLDFILE);
  7. if (fh)
  8. {
  9. int dimsok = 0, width, height;
  10. char r;
  11. char buffer[25 + 1] = {0};
  12.  
  13. SetMode(fh, 1); // RAW mode
  14.  
  15. if (Write(fh, "\x9b q", 3) == 3)
  16. {
  17. LONG actual = 0;
  18. LONG ret = Read(fh, r, 1);
  19. while (r != 'r' && ret != 0)
  20. {
  21. buffer[actual] = r;
  22. actual += ret;
  23. ret = Read(fh, r, 1);
  24. }
  25. if (actual >= 0)
  26. {
  27. buffer[actual] = '\0';
  28. if (sscanf(buffer, "\x9b"
  29. "1;1;%d;%d r",
  30. &height, &width) == 2)
  31. {
  32. dimsok = 1;
  33. }
  34. }
  35. }
  36.  
  37. SetMode(fh, 0); // Normal mode
  38.  
  39. Close(fh);
  40. if (dimsok)
  41. {
  42. printf("console dimensions: %ld x %ld\n", width, height);
  43. }
  44. }
  45. else
  46. Printf("Cannot open CONSOLE:\n");
  47. return 0;
  48. }
hypex
hypex's picture
Offline
Last seen: 1 month 2 weeks ago
Joined: 2011-09-09 16:20
Re: Console Device.

The funny thing is that if you resize the window the content is repainted correcty. I've sent a message to Tony to see if he can reproduce the problem

Any answers yet?

I'll test this method to see if i have the same problem. Howerver since there is a new Command in console.device why don't use it?

For one thing the overhead and extra code in using the console.device. If you need to use it for other direct access that is fine. But it's one of those Amigaisms where you need all this code to find a small piece of infomation.

OTOH, the older method just uses a file handle, and you can even grab it with Input() or Output().

I didn't try. However i get the code from the example i've found on amiga.org.

What's your compile line for the code below? I almost got it but forget what define you need to avoid interfaces. And couldn't find it in the SDK PDF.

afxgroup
afxgroup's picture
Offline
Last seen: 10 months 2 weeks ago
Joined: 2011-02-03 15:26
Re: Console Device.

ppc-amigaos-gcc console.c -o console -D__USE_INLINE__ -lauto

Log in or register to post comments