brianm@sco.COM (Brian Moffet) (11/17/88)
1) Well, I was sitting at my desk one day hacking together a small program and wanted to get keyboard input from a custom window. Now I didn't want to attach a console device to this sucker, so I thought, "Hey, I can use Vanillakeys!" (sounds sort of like an IceCream sold off the coast of florida). However, I am able to recieve normal key strokes, but not the function keys. Does anyone know why this might be? I don't appear to be getting a message even. Note: I am using ConMan (fantastic program by the way) and I am not sure if that has made a difference. 2) 1 bitplane workbench. Is it possible to just free the bitmap and rearrange the WB screen structure to get this to work? Seems simple enough so that I'll try it. 3) In the same program as #1, I poll a windows IDCMP message port using GetMsg(W->UserPort). If I receive a message I will take some action. This action may be to go to a subroutine which does a Wait(1<<W->UserPort->mp_SigBit). When this happens, the wait will succeed when there is no new message. It apparently sees that there was a message. I do ReplyMsg() properly, so I am not sure what is going on. -=-=-=-=-sample code fragment-=-=-=-=- while((mp = GetMsg(up)) == NULL); ReplyMsg(mp); Wait(1<<up->mp_SigBit); /* This returns immediatly */ Does this behaviour seem proper? I would think the ReplyMsg would clear things out. Is there a proper way of clearing the signal? Again, thanks for all the help. I look forward to the 2500 and possibly the 3000, maybe I'll upgrade my 1000. brian m. PS Matt, could you get in touch with me? I had a hard disk crash and lost your latest version of dmouse. I have the source, but not the binary or a Manx compiler. tanx -- Brian Moffet {uunet,decvax!microsoft,ucscc}!sco!brianm -or- ...sco!alar!brian "Evil Geniuses for a better tomorrow!" My fish and company have policies. I have opinions.
phil@titan.rice.edu (William LeFebvre) (11/18/88)
In article <1732@scolex> brianm@sco.COM (Brian Moffet) writes: >3) In the same program as #1, I poll a windows IDCMP message >port using GetMsg(W->UserPort). If I receive a message I will >take some action. This action may be to go to a subroutine >which does a Wait(1<<W->UserPort->mp_SigBit). >When this happens, the wait will succeed when there is no new >message. It apparently sees that there was a message. I do >ReplyMsg() properly, so I am not sure what is going on. > >-=-=-=-=-sample code fragment-=-=-=-=- > while((mp = GetMsg(up)) == NULL); > ReplyMsg(mp); > Wait(1<<up->mp_SigBit); /* This returns immediatly */ That program fragment seems improper to me. I don't have my RKM handy (being at school right now), but I would guess that GetMsg returns NULL if there is no message available. That while loop then is basically busy waiting. This is a big no-no in a multitasking environment. The proper way to do this is to Wait first, then GetMsg. This will take care of your problem (the signal gets reset by the wait and doesn't need to be reset by the reply) and will also keep your program from busy waiting. Now if you just want to poll the port via GetMsg, and do something else if no message was there, then that's different: =-=-=-=-=-sample code fragment-=-=-=-=- if ((mp = GetMsg(up)) == NULL) { ... something else ... } else { ReplyMsg(mp); Wait(1<<up->mp_SigBit); /* ??? */ ... } Without the RKM's, I can't recall how one would go about clearing the signal. Doing a Wait after the GetMsg seems wrong to me, but that may be the way to do it (I think that it would be guaranteed not to block in that instance). In my example, replacing "if" with "while" would be okay, provided that the body of the loop was actually doing something constructive. William LeFebvre Department of Computer Science Rice University <phil@Rice.edu>
dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) (11/20/88)
:In article <1732@scolex> brianm@sco.COM (Brian Moffet) writes: :>3) In the same program as #1, I poll a windows IDCMP message :>port using GetMsg(W->UserPort). If I receive a message I will :>take some action. This action may be to go to a subroutine :>which does a Wait(1<<W->UserPort->mp_SigBit). :>When this happens, the wait will succeed when there is no new :>message. It apparently sees that there was a message. I do :>ReplyMsg() properly, so I am not sure what is going on. :> :>-=-=-=-=-sample code fragment-=-=-=-=- :> while((mp = GetMsg(up)) == NULL); :> ReplyMsg(mp); :> Wait(1<<up->mp_SigBit); /* This returns immediatly */ Completely wrong, the program will freeze! (1) You busy wait in the while(), GetMsg() does NOT block, but returns NULL if no message is ready. This in itself is a big no-no. (2) You process just a single message and then you Wait(). Contrary to your comment, Wait() will NOT return immediately every time and you can get into a lockout situation Example: Intuition sends three messages to you. This causes the proper signal bit to be set. Your while ends and returns the first message which is then replied. you then Wait() which returns immediately and CLEARS the signal bit. You then loop up to the top and do the while() again. The while returns the second message, you reply, but now since the signal bit is cleared, the Wait() waits forever even though there is a third intuition message waiting. (actually, if intuition queues a fifth message it will unstick, but by this time it has gotten N messages off and will never process all of them). Your code counts on intuition sending messages one at a time, which it does not do... intuition might queue any number of messages before your process has a chance to process any of them! PROPER CODE while (notdone) { Wait(1 << up->mp_SigBit); while (msg = GetMsg(up)) { <process the message> ReplyMsg(msg); } } CloseWindow(window); /* automagically removes any yet-to-be GetMsg()d messages before closing down */ Note that here I process ALL messages before looping. In this case, the only possibility of possibly incorrect operation occurs if I get a new message while processing previous messages. The new message sets the signal bit, but it is also handled by the while() loop, which means when the for(;;) loops up Wait() will return immediately and go through a 'dummy-pass' on the GetMsg() (GetMsg() will return NULL and we will go and Wait() again, this time Wait() really will Wait!). -Matt
brianm@sco.COM (Brian Moffet) (11/22/88)
In article <8811200120.AA29916@postgres.Berkeley.EDU> dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) writes: >:In article <1732@scolex> brianm@sco.COM (Brian Moffet) writes: >:>3) In the same program as #1, I poll a windows IDCMP message >:>port using GetMsg(W->UserPort). If I receive a message I will >:>take some action. This action may be to go to a subroutine >:>which does a Wait(1<<W->UserPort->mp_SigBit). >:>When this happens, the wait will succeed when there is no new >:>message. It apparently sees that there was a message. I do >:>ReplyMsg() properly, so I am not sure what is going on. >:> >:>-=-=-=-=-sample code fragment-=-=-=-=- >:> while((mp = GetMsg(up)) == NULL); >:> ReplyMsg(mp); >:> Wait(1<<up->mp_SigBit); /* This returns immediatly */ > > Completely wrong, the program will freeze! > > (1) You busy wait in the while(), GetMsg() does NOT block, but returns > NULL if no message is ready. This in itself is a big no-no. I know it is a no-no. However, in the hopes for small code fragments it is okay. The program will end when a message is recieved. > > (2) You process just a single message and then you Wait(). Contrary > to your comment, Wait() will NOT return immediately every time > and you can get into a lockout situation > It will return immediately if there has been a GetMsg() loop going on before hand (with appropriate ReplyMsg()ing) with no Wait() calls. This is my question: Why? Hmm, people seem to have mistaken what was going on. I will explain. I have a program which is a graphics program. It basically does calculations etc, for each pixel. After writing that pixel I do a GetMsg(). This is for the closewindow gadget. If this has happened, I return from the subroutine which is doing the calculating. I then will do a Wait() for further action. It is this wait that returns immediatly. I then do a GetMsg() to see what happened, and GetMsg() returns NULL. the only thing I can assume is the signal is not cleared. A better *but longer* example is: main() { : : : Do_Calc(); while (1) { /* this wait will return first time */ Wait( 1 << mp->Sig_Bit ); while ( (msg = GetMsg(up)) != NULL ) { class = msg->Class; code = msg->Code; ReplyMsg(msg); Process_Msg(code, class); /* this will exit */ } } : : } Do_Calc() { : : ret = 0; while (1) { : : while ((msg = GetMsg(up)) != NULL) { ret = 1; ReplyMsg(msg); } if (ret) return; } } i had hoped that people would be able to figure out what I was talking about without so much code, but ah well. Now, why does the wait return the first time, but the GetMsg() returns NULL? brian moffet -- Brian Moffet {uunet,decvax!microsoft,ucscc}!sco!brianm -or- ...sco!alar!brian "Evil Geniuses for a better tomorrow!" My fish and company have policies. I have opinions.
cmcmanis%pepper@Sun.COM (Chuck McManis) (11/22/88)
Two problems that brian moffett is looking at and the solutions are pretty general. 1) VANILLAKEYS are just that, vanilla. No function keys, no help keys. I believe they are poorly defined and should be redefined but that is up to jimm and company. The workaround is to use RAWKEYS and DeadKeyConvert() whose source is around on Fish disks and various other places. Bryce Nesbitt wrote an article for AmigaMail that had this information in it. 2) The way he was reaping IntuiMessages was also incorrect, this will definitely be one of the questions on the Intuition Merit Badge "test." The key is that signals let you know when to look for messages, you then have to look for all messages that exist. Matt's code fragment was excellent, it is repeated (paraphrased?) here for completeness : WINDOWSIG = 1L << win->UserPort->mp_SigBit; SIGNALMASK = WINDOWSIG; /* Add any other signals to this mask */ for (;;) { /* for ever and ever */ signals = Wait(SIGNALMASK); if ((signals & WINDOWSIG) != 0) { While ((msg = GetMessage(win->UserPort)) != NULL) { switch (msg->Class) { /* Process messages from Intuition */ } ReplyMsg(msg); /* do this quickly */ } /* fall through to check for other signals */ } if (/* check for each type of signal */) { } } /* loop forever unless explicitly exit. */ The key features are that you wait first, this gives up the processor for other tasks until something happens that your task should know about. Then you process *all* of the messages waiting on your message port, and then you *still* check to see if other signals were set. This allows one loop to process things like serial characters, window events, break signals etc. --Chuck McManis uucp: {anywhere}!sun!cmcmanis BIX: cmcmanis ARPAnet: cmcmanis@sun.com These opinions are my own and no one elses, but you knew that didn't you.
cmcmanis%pepper@Sun.COM (Chuck McManis) (11/23/88)
In article <1769@scolex> brianm@sco.COM (Brian Moffet) writes: >It is this wait that returns immediatly. I then do a GetMsg() >to see what happened, and GetMsg() returns NULL. the >only thing I can assume is the signal is not cleared. Right-o. And you don't have to even assume it, it's documented that Wait() clears signals and GetMsg() doesn't do anything to signals. The CLOSEWINDOW message sets the signal, you read it before looking at the signal, then when you go to check the signal with a Wait() it returns immediately because the signal is set but the message has already been processed hence the null return from GetMsg(). --Chuck McManis uucp: {anywhere}!sun!cmcmanis BIX: cmcmanis ARPAnet: cmcmanis@sun.com These opinions are my own and no one elses, but you knew that didn't you.
dillon@POSTGRES.BERKELEY.EDU (Matt Dillon) (11/23/88)
:Hmm, people seem to have mistaken what was going on. I will explain. :I have a program which is a graphics program. It basically does :calculations etc, for each pixel. After writing that pixel :I do a GetMsg(). This is for the closewindow gadget. If this :has happened, I return from the subroutine which is doing the :calculating. I then will do a Wait() for further action. : :It is this wait that returns immediatly. I then do a GetMsg() :to see what happened, and GetMsg() returns NULL. the :only thing I can assume is the signal is not cleared. Ohhh.. sorry. Easy to explain: The GetMsg() call in itself does NOT clear the signal bit. Thus, when intuition sends the CLOSEWINDOW IDCMP, this both sets the signal and places the message on the UserPort. You then GetMsg() it (which does not clear the signal). You then Wait() on the signal, which returns immediately because the signal was set. A further GetMsg() results in NULL (unless intuition sent you a second message). The Wait() call clears the signal. Now, you must ReplyMsg() ANY message you have successfully retrieved via GetMsg(). main() { short notdone = 1; .... while (notdone) { WriteThePixel() if (imess = GetMsg(UserPort)) { long class = imess->Class; ReplyMsg(imess); if (class == CLOSEWINDOW) notdone = 0; } } CloseWindow(Win); } Of course, once you finish rendering and are 'Idle' waiting for the window to be closed you would put a Wait(1 << UserPort->mp_SigBit) in the loop: while (notdone) { Wait(1 << UserPort->mp_SigBit); /* OR WaitPort(UserPort) */ while (imess = GetMsg(UserPort)) { /* process the message */ ReplyMsg(imess); /* you must reply it */ } } Where, due to timing, there are bound to be cases where the Wait() returns and the GetMsg() comes back NULL the first time, but the way the loop is setup it doesn't matter. The most common mistake is to break out of the loop when you get the CLOSEWINDOW IDCMP and forgetting to ReplyMsg() it. By using a 'notdone' variable you can avoid the mistake, because then all you would do when you get the CLOSEWINDOW is clear the variable and continue normally (ReplyMsg()ing it and handling any further messages). -Matt
ng@pur-phy (Nicholas J. Giordano) (11/23/88)
In article <78687@sun.uucp> cmcmanis@sun.UUCP (Chuck McManis) writes: >Two problems that brian moffett is looking at and the solutions are >pretty general. > >1) VANILLAKEYS are just that, vanilla. No function keys, no help >keys. I believe they are poorly defined and should be redefined but >that is up to jimm and company. > >The workaround is to use RAWKEYS and DeadKeyConvert() whose source >is around on Fish disks and various other places. Bryce Nesbitt >wrote an article for AmigaMail that had this information in it. There is another way, which is not much work, but gets just about all the keyboard information you USUALLY need. It is to attach a console.device to the window, and do all keyboard input/output through it. This gives you access to all the function keys, help keys, arrow keys, etc., in an ANSI manner. I think its easier to use than DeadKeyConvert(), and the information that the console.device doesn't give (like when a key is released) is often not needed anyway. An example of this can be found in John Toebes (sp?) article in the first (or second) Transactor issue, and in Matt Dillon's terminal server for DNET. They and others on the net put me on to this approach, and its worked great for me. Nick